diff -r 0384683c64be -r ddb4a2bfcd82 src/share/classes/com/sun/tools/javac/comp/MemberEnter.java --- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Tue May 14 13:55:35 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Tue May 14 15:04:06 2013 -0700 @@ -31,7 +31,6 @@ import java.util.Map; import java.util.Set; -import javax.lang.model.type.TypeKind; import javax.tools.JavaFileObject; import com.sun.tools.javac.code.*; @@ -617,7 +616,26 @@ if (TreeInfo.isEnumInit(tree)) { attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype); } else { + // Make sure type annotations are processed. + // But we don't have a symbol to attach them to yet - use null. + typeAnnotate(tree.vartype, env, null); attr.attribType(tree.vartype, localEnv); + if (tree.nameexpr != null) { + attr.attribExpr(tree.nameexpr, localEnv); + MethodSymbol m = localEnv.enclMethod.sym; + if (m.isConstructor()) { + Type outertype = m.owner.owner.type; + if (outertype.hasTag(TypeTag.CLASS)) { + checkType(tree.vartype, outertype, "incorrect.constructor.receiver.type"); + checkType(tree.nameexpr, outertype, "incorrect.constructor.receiver.name"); + } else { + log.error(tree, "receiver.parameter.not.applicable.constructor.toplevel.class"); + } + } else { + checkType(tree.vartype, m.owner.type, "incorrect.receiver.type"); + checkType(tree.nameexpr, m.owner.type, "incorrect.receiver.name"); + } + } } } finally { chk.setDeferredLintHandler(prevLintHandler); @@ -651,10 +669,16 @@ enclScope.enter(v); } annotateLater(tree.mods.annotations, localEnv, v); - typeAnnotate(tree.vartype, env, tree.sym); + typeAnnotate(tree.vartype, env, v); annotate.flush(); v.pos = tree.pos; } + // where + void checkType(JCTree tree, Type type, String diag) { + if (!tree.type.isErroneous() && !types.isSameType(tree.type, type)) { + log.error(tree, diag, type, tree.type); + } + } /** Create a fresh environment for a variable's initializer. * If the variable is a field, the owner of the environment's scope @@ -1040,9 +1064,12 @@ isFirst = true; } } - annotate.afterRepeated(TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, tree)); + TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, tree, annotate); } + /* + * If the symbol is non-null, attach the type annotation to it. + */ private void actualEnterTypeAnnotations(final List annotations, final Env env, final Symbol s) { @@ -1075,8 +1102,10 @@ } } - s.annotations.appendTypeAttributesWithCompletion( - annotate.new AnnotateRepeatedContext(env, annotated, pos, log, true)); + if (s != null) { + s.annotations.appendTypeAttributesWithCompletion( + annotate.new AnnotateRepeatedContext(env, annotated, pos, log, true)); + } } public void typeAnnotate(final JCTree tree, final Env env, final Symbol sym) { @@ -1150,6 +1179,33 @@ // Do not annotate the body, just the signature. // scan(tree.body); } + + @Override + public void visitVarDef(final JCVariableDecl tree) { + if (sym != null && sym.kind == Kinds.VAR) { + // Don't visit a parameter once when the sym is the method + // and once when the sym is the parameter. + scan(tree.mods); + scan(tree.vartype); + } + scan(tree.init); + } + + @Override + public void visitClassDef(JCClassDecl tree) { + // We can only hit a classdef if it is declared within + // a method. Ignore it - the class will be visited + // separately later. + } + + @Override + public void visitNewClass(JCNewClass tree) { + if (tree.def == null) { + // For an anonymous class instantiation the class + // will be visited separately. + super.visitNewClass(tree); + } + } }