8054448: (ann) Cannot reference field of inner class in an anonymous class
authorjfranck
Fri, 24 Oct 2014 08:34:51 +0200
changeset 27231 c1ca668b421e
parent 27230 361efbfa3079
child 27232 85cb761ea65c
8054448: (ann) Cannot reference field of inner class in an anonymous class Reviewed-by: jlahoda, mcimadamore
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java
langtools/test/tools/javac/annotations/FinalStringInNested.java
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Oct 24 10:54:04 2014 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Oct 24 08:34:51 2014 +0200
@@ -989,8 +989,12 @@
                 // parameters have already been entered
                 env.info.scope.enter(tree.sym);
             } else {
-                memberEnter.memberEnter(tree, env);
-                annotate.flush();
+                try {
+                    annotate.enterStart();
+                    memberEnter.memberEnter(tree, env);
+                } finally {
+                    annotate.enterDone();
+                }
             }
         } else {
             if (tree.init != null) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Fri Oct 24 10:54:04 2014 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Fri Oct 24 08:34:51 2014 +0200
@@ -518,52 +518,46 @@
         }
 
         Env<AttrContext> localEnv = methodEnv(tree, env);
-
-        annotate.enterStart();
+        DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
         try {
-            DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
-            try {
-                // Compute the method type
-                m.type = signature(m, tree.typarams, tree.params,
-                                   tree.restype, tree.recvparam,
-                                   tree.thrown,
-                                   localEnv);
-            } finally {
-                deferredLintHandler.setPos(prevLintPos);
-            }
+            // Compute the method type
+            m.type = signature(m, tree.typarams, tree.params,
+                               tree.restype, tree.recvparam,
+                               tree.thrown,
+                               localEnv);
+        } finally {
+            deferredLintHandler.setPos(prevLintPos);
+        }
 
-            if (types.isSignaturePolymorphic(m)) {
-                m.flags_field |= SIGNATURE_POLYMORPHIC;
-            }
+        if (types.isSignaturePolymorphic(m)) {
+            m.flags_field |= SIGNATURE_POLYMORPHIC;
+        }
 
-            // Set m.params
-            ListBuffer<VarSymbol> params = new ListBuffer<>();
-            JCVariableDecl lastParam = null;
-            for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
-                JCVariableDecl param = lastParam = l.head;
-                params.append(Assert.checkNonNull(param.sym));
-            }
-            m.params = params.toList();
+        // Set m.params
+        ListBuffer<VarSymbol> params = new ListBuffer<>();
+        JCVariableDecl lastParam = null;
+        for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
+            JCVariableDecl param = lastParam = l.head;
+            params.append(Assert.checkNonNull(param.sym));
+        }
+        m.params = params.toList();
 
-            // mark the method varargs, if necessary
-            if (lastParam != null && (lastParam.mods.flags & Flags.VARARGS) != 0)
-                m.flags_field |= Flags.VARARGS;
+        // mark the method varargs, if necessary
+        if (lastParam != null && (lastParam.mods.flags & Flags.VARARGS) != 0)
+            m.flags_field |= Flags.VARARGS;
 
-            localEnv.info.scope.leave();
-            if (chk.checkUnique(tree.pos(), m, enclScope)) {
-            enclScope.enter(m);
-            }
+        localEnv.info.scope.leave();
+        if (chk.checkUnique(tree.pos(), m, enclScope)) {
+        enclScope.enter(m);
+        }
 
-            annotate.annotateLater(tree.mods.annotations, localEnv, m, tree.pos());
-            // Visit the signature of the method. Note that
-            // TypeAnnotate doesn't descend into the body.
-            annotate.annotateTypeLater(tree, localEnv, m, tree.pos());
+        annotate.annotateLater(tree.mods.annotations, localEnv, m, tree.pos());
+        // Visit the signature of the method. Note that
+        // TypeAnnotate doesn't descend into the body.
+        annotate.annotateTypeLater(tree, localEnv, m, tree.pos());
 
-            if (tree.defaultValue != null)
-                annotateDefaultValueLater(tree.defaultValue, localEnv, m);
-        } finally {
-            annotate.enterDone();
-        }
+        if (tree.defaultValue != null)
+            annotateDefaultValueLater(tree.defaultValue, localEnv, m);
     }
 
     /** Create a fresh environment for method bodies.
@@ -591,56 +585,51 @@
             localEnv.info.staticLevel++;
         }
         DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
-        annotate.enterStart();
         try {
-            try {
-                if (TreeInfo.isEnumInit(tree)) {
-                    attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype);
-                } else {
-                    attr.attribType(tree.vartype, localEnv);
-                    if (TreeInfo.isReceiverParam(tree))
-                        checkReceiver(tree, localEnv);
-                }
-            } finally {
-                deferredLintHandler.setPos(prevLintPos);
-            }
-
-            if ((tree.mods.flags & VARARGS) != 0) {
-                //if we are entering a varargs parameter, we need to
-                //replace its type (a plain array type) with the more
-                //precise VarargsType --- we need to do it this way
-                //because varargs is represented in the tree as a
-                //modifier on the parameter declaration, and not as a
-                //distinct type of array node.
-                ArrayType atype = (ArrayType)tree.vartype.type;
-                tree.vartype.type = atype.makeVarargs();
+            if (TreeInfo.isEnumInit(tree)) {
+                attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype);
+            } else {
+                attr.attribType(tree.vartype, localEnv);
+                if (TreeInfo.isReceiverParam(tree))
+                    checkReceiver(tree, localEnv);
             }
-            WriteableScope enclScope = enter.enterScope(env);
-            VarSymbol v =
-                new VarSymbol(0, tree.name, tree.vartype.type, enclScope.owner);
-            v.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, v, tree);
-            tree.sym = v;
-            if (tree.init != null) {
-                v.flags_field |= HASINIT;
-                if ((v.flags_field & FINAL) != 0 &&
-                    needsLazyConstValue(tree.init)) {
-                    Env<AttrContext> initEnv = getInitEnv(tree, env);
-                    initEnv.info.enclVar = v;
-                    v.setLazyConstValue(initEnv(tree, initEnv), attr, tree);
-                }
+        } finally {
+            deferredLintHandler.setPos(prevLintPos);
+        }
+
+        if ((tree.mods.flags & VARARGS) != 0) {
+            //if we are entering a varargs parameter, we need to
+            //replace its type (a plain array type) with the more
+            //precise VarargsType --- we need to do it this way
+            //because varargs is represented in the tree as a
+            //modifier on the parameter declaration, and not as a
+            //distinct type of array node.
+            ArrayType atype = (ArrayType)tree.vartype.type;
+            tree.vartype.type = atype.makeVarargs();
+        }
+        WriteableScope enclScope = enter.enterScope(env);
+        VarSymbol v =
+            new VarSymbol(0, tree.name, tree.vartype.type, enclScope.owner);
+        v.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, v, tree);
+        tree.sym = v;
+        if (tree.init != null) {
+            v.flags_field |= HASINIT;
+            if ((v.flags_field & FINAL) != 0 &&
+                needsLazyConstValue(tree.init)) {
+                Env<AttrContext> initEnv = getInitEnv(tree, env);
+                initEnv.info.enclVar = v;
+                v.setLazyConstValue(initEnv(tree, initEnv), attr, tree);
             }
-            if (chk.checkUnique(tree.pos(), v, enclScope)) {
-                chk.checkTransparentVar(tree.pos(), v, enclScope);
-                enclScope.enter(v);
-            }
+        }
+        if (chk.checkUnique(tree.pos(), v, enclScope)) {
+            chk.checkTransparentVar(tree.pos(), v, enclScope);
+            enclScope.enter(v);
+        }
 
-            annotate.annotateLater(tree.mods.annotations, localEnv, v, tree.pos());
-            annotate.annotateTypeLater(tree.vartype, localEnv, v, tree.pos());
+        annotate.annotateLater(tree.mods.annotations, localEnv, v, tree.pos());
+        annotate.annotateTypeLater(tree.vartype, localEnv, v, tree.pos());
 
-            v.pos = tree.pos;
-        } finally {
-            annotate.enterDone();
-        }
+        v.pos = tree.pos;
     }
     // where
     void checkType(JCTree tree, Type type, String diag) {
@@ -866,219 +855,225 @@
             return;
         }
 
-        ClassSymbol c = (ClassSymbol)sym;
-        ClassType ct = (ClassType)c.type;
-        Env<AttrContext> env = typeEnvs.get(c);
-        JCClassDecl tree = (JCClassDecl)env.tree;
-        boolean wasFirst = isFirst;
-        isFirst = false;
+        try {
+            annotate.enterStart();
+
+            ClassSymbol c = (ClassSymbol)sym;
+            ClassType ct = (ClassType)c.type;
+            Env<AttrContext> env = typeEnvs.get(c);
+            JCClassDecl tree = (JCClassDecl)env.tree;
+            boolean wasFirst = isFirst;
+            isFirst = false;
+
+            JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
+            DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
+            try {
+                dependencies.push(c);
+
+                // Save class environment for later member enter (2) processing.
+                halfcompleted.append(env);
 
-        JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
-        DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
-        try {
-            dependencies.push(c);
+                // Mark class as not yet attributed.
+                c.flags_field |= UNATTRIBUTED;
+
+                // If this is a toplevel-class, make sure any preceding import
+                // clauses have been seen.
+                if (c.owner.kind == PCK) {
+                    memberEnter(env.toplevel, env.enclosing(TOPLEVEL));
+                    todo.append(env);
+                }
 
-            // Save class environment for later member enter (2) processing.
-            halfcompleted.append(env);
+                if (c.owner.kind == TYP)
+                    c.owner.complete();
+
+                // create an environment for evaluating the base clauses
+                Env<AttrContext> baseEnv = baseEnv(tree, env);
 
-            // Mark class as not yet attributed.
-            c.flags_field |= UNATTRIBUTED;
+                if (tree.extending != null)
+                    annotate.annotateTypeLater(tree.extending, baseEnv, sym, tree.pos());
+                for (JCExpression impl : tree.implementing)
+                    annotate.annotateTypeLater(impl, baseEnv, sym, tree.pos());
+                annotate.flush();
 
-            // If this is a toplevel-class, make sure any preceding import
-            // clauses have been seen.
-            if (c.owner.kind == PCK) {
-                memberEnter(env.toplevel, env.enclosing(TOPLEVEL));
-                todo.append(env);
-            }
-
-            if (c.owner.kind == TYP)
-                c.owner.complete();
-
-            // create an environment for evaluating the base clauses
-            Env<AttrContext> baseEnv = baseEnv(tree, env);
+                // Determine supertype.
+                Type supertype;
+                if (tree.extending != null) {
+                    dependencies.push(AttributionKind.EXTENDS, tree.extending);
+                    try {
+                        supertype = attr.attribBase(tree.extending, baseEnv,
+                                true, false, true);
+                    } finally {
+                        dependencies.pop();
+                    }
+                } else {
+                    supertype = ((tree.mods.flags & Flags.ENUM) != 0)
+                    ? attr.attribBase(enumBase(tree.pos, c), baseEnv,
+                                      true, false, false)
+                    : (c.fullname == names.java_lang_Object)
+                    ? Type.noType
+                    : syms.objectType;
+                }
+                ct.supertype_field = modelMissingTypes(supertype, tree.extending, false);
 
-            if (tree.extending != null)
-                annotate.annotateTypeLater(tree.extending, baseEnv, sym, tree.pos());
-            for (JCExpression impl : tree.implementing)
-                annotate.annotateTypeLater(impl, baseEnv, sym, tree.pos());
-            annotate.flush();
+                // Determine interfaces.
+                ListBuffer<Type> interfaces = new ListBuffer<>();
+                ListBuffer<Type> all_interfaces = null; // lazy init
+                Set<Type> interfaceSet = new HashSet<>();
+                List<JCExpression> interfaceTrees = tree.implementing;
+                for (JCExpression iface : interfaceTrees) {
+                    dependencies.push(AttributionKind.IMPLEMENTS, iface);
+                    try {
+                        Type it = attr.attribBase(iface, baseEnv, false, true, true);
+                        if (it.hasTag(CLASS)) {
+                            interfaces.append(it);
+                            if (all_interfaces != null) all_interfaces.append(it);
+                            chk.checkNotRepeated(iface.pos(), types.erasure(it), interfaceSet);
+                        } else {
+                            if (all_interfaces == null)
+                                all_interfaces = new ListBuffer<Type>().appendList(interfaces);
+                            all_interfaces.append(modelMissingTypes(it, iface, true));
+                        }
+                    } finally {
+                        dependencies.pop();
+                    }
+                }
 
-            // Determine supertype.
-            Type supertype;
-            if (tree.extending != null) {
-                dependencies.push(AttributionKind.EXTENDS, tree.extending);
-                try {
-                    supertype = attr.attribBase(tree.extending, baseEnv,
-                            true, false, true);
-                } finally {
-                    dependencies.pop();
+                if ((c.flags_field & ANNOTATION) != 0) {
+                    ct.interfaces_field = List.of(syms.annotationType);
+                    ct.all_interfaces_field = ct.interfaces_field;
+                }  else {
+                    ct.interfaces_field = interfaces.toList();
+                    ct.all_interfaces_field = (all_interfaces == null)
+                            ? ct.interfaces_field : all_interfaces.toList();
                 }
-            } else {
-                supertype = ((tree.mods.flags & Flags.ENUM) != 0)
-                ? attr.attribBase(enumBase(tree.pos, c), baseEnv,
-                                  true, false, false)
-                : (c.fullname == names.java_lang_Object)
-                ? Type.noType
-                : syms.objectType;
-            }
-            ct.supertype_field = modelMissingTypes(supertype, tree.extending, false);
+
+                if (c.fullname == names.java_lang_Object) {
+                    if (tree.extending != null) {
+                        chk.checkNonCyclic(tree.extending.pos(),
+                                           supertype);
+                        ct.supertype_field = Type.noType;
+                    }
+                    else if (tree.implementing.nonEmpty()) {
+                        chk.checkNonCyclic(tree.implementing.head.pos(),
+                                           ct.interfaces_field.head);
+                        ct.interfaces_field = List.nil();
+                    }
+                }
+
+                // Annotations.
+                // In general, we cannot fully process annotations yet,  but we
+                // can attribute the annotation types and then check to see if the
+                // @Deprecated annotation is present.
+                attr.attribAnnotationTypes(tree.mods.annotations, baseEnv);
+                if (hasDeprecatedAnnotation(tree.mods.annotations))
+                    c.flags_field |= DEPRECATED;
+                annotate.annotateLater(tree.mods.annotations, baseEnv,
+                            c, tree.pos());
+
+                chk.checkNonCyclicDecl(tree);
+
+                // class type parameters use baseEnv but everything uses env
+                attr.attribTypeVariables(tree.typarams, baseEnv);
+                for (JCTypeParameter tp : tree.typarams)
+                    annotate.annotateTypeLater(tp, baseEnv, sym, tree.pos());
 
-            // Determine interfaces.
-            ListBuffer<Type> interfaces = new ListBuffer<>();
-            ListBuffer<Type> all_interfaces = null; // lazy init
-            Set<Type> interfaceSet = new HashSet<>();
-            List<JCExpression> interfaceTrees = tree.implementing;
-            for (JCExpression iface : interfaceTrees) {
-                dependencies.push(AttributionKind.IMPLEMENTS, iface);
-                try {
-                    Type it = attr.attribBase(iface, baseEnv, false, true, true);
-                    if (it.hasTag(CLASS)) {
-                        interfaces.append(it);
-                        if (all_interfaces != null) all_interfaces.append(it);
-                        chk.checkNotRepeated(iface.pos(), types.erasure(it), interfaceSet);
-                    } else {
-                        if (all_interfaces == null)
-                            all_interfaces = new ListBuffer<Type>().appendList(interfaces);
-                        all_interfaces.append(modelMissingTypes(it, iface, true));
+                // Add default constructor if needed.
+                if ((c.flags() & INTERFACE) == 0 &&
+                    !TreeInfo.hasConstructors(tree.defs)) {
+                    List<Type> argtypes = List.nil();
+                    List<Type> typarams = List.nil();
+                    List<Type> thrown = List.nil();
+                    long ctorFlags = 0;
+                    boolean based = false;
+                    boolean addConstructor = true;
+                    JCNewClass nc = null;
+                    if (c.name.isEmpty()) {
+                        nc = (JCNewClass)env.next.tree;
+                        if (nc.constructor != null) {
+                            addConstructor = nc.constructor.kind != ERR;
+                            Type superConstrType = types.memberType(c.type,
+                                                                    nc.constructor);
+                            argtypes = superConstrType.getParameterTypes();
+                            typarams = superConstrType.getTypeArguments();
+                            ctorFlags = nc.constructor.flags() & VARARGS;
+                            if (nc.encl != null) {
+                                argtypes = argtypes.prepend(nc.encl.type);
+                                based = true;
+                            }
+                            thrown = superConstrType.getThrownTypes();
+                        }
                     }
-                } finally {
-                    dependencies.pop();
+                    if (addConstructor) {
+                        MethodSymbol basedConstructor = nc != null ?
+                                (MethodSymbol)nc.constructor : null;
+                        JCTree constrDef = DefaultConstructor(make.at(tree.pos), c,
+                                                            basedConstructor,
+                                                            typarams, argtypes, thrown,
+                                                            ctorFlags, based);
+                        tree.defs = tree.defs.prepend(constrDef);
+                    }
                 }
-            }
 
-            if ((c.flags_field & ANNOTATION) != 0) {
-                ct.interfaces_field = List.of(syms.annotationType);
-                ct.all_interfaces_field = ct.interfaces_field;
-            }  else {
-                ct.interfaces_field = interfaces.toList();
-                ct.all_interfaces_field = (all_interfaces == null)
-                        ? ct.interfaces_field : all_interfaces.toList();
-            }
+                // enter symbols for 'this' into current scope.
+                VarSymbol thisSym =
+                    new VarSymbol(FINAL | HASINIT, names._this, c.type, c);
+                thisSym.pos = Position.FIRSTPOS;
+                env.info.scope.enter(thisSym);
+                // if this is a class, enter symbol for 'super' into current scope.
+                if ((c.flags_field & INTERFACE) == 0 &&
+                        ct.supertype_field.hasTag(CLASS)) {
+                    VarSymbol superSym =
+                        new VarSymbol(FINAL | HASINIT, names._super,
+                                      ct.supertype_field, c);
+                    superSym.pos = Position.FIRSTPOS;
+                    env.info.scope.enter(superSym);
+                }
 
-            if (c.fullname == names.java_lang_Object) {
-                if (tree.extending != null) {
-                    chk.checkNonCyclic(tree.extending.pos(),
-                                       supertype);
-                    ct.supertype_field = Type.noType;
+                // check that no package exists with same fully qualified name,
+                // but admit classes in the unnamed package which have the same
+                // name as a top-level package.
+                if (checkClash &&
+                    c.owner.kind == PCK && c.owner != syms.unnamedPackage &&
+                    syms.packageExists(c.fullname)) {
+                    log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), c);
                 }
-                else if (tree.implementing.nonEmpty()) {
-                    chk.checkNonCyclic(tree.implementing.head.pos(),
-                                       ct.interfaces_field.head);
-                    ct.interfaces_field = List.nil();
+                if (c.owner.kind == PCK && (c.flags_field & PUBLIC) == 0 &&
+                    !env.toplevel.sourcefile.isNameCompatible(c.name.toString(),JavaFileObject.Kind.SOURCE)) {
+                    c.flags_field |= AUXILIARY;
                 }
+            } catch (CompletionFailure ex) {
+                chk.completionError(tree.pos(), ex);
+            } finally {
+                deferredLintHandler.setPos(prevLintPos);
+                log.useSource(prev);
+                dependencies.pop();
             }
 
-            // Annotations.
-            // In general, we cannot fully process annotations yet,  but we
-            // can attribute the annotation types and then check to see if the
-            // @Deprecated annotation is present.
-            attr.attribAnnotationTypes(tree.mods.annotations, baseEnv);
-            if (hasDeprecatedAnnotation(tree.mods.annotations))
-                c.flags_field |= DEPRECATED;
-            annotate.annotateLater(tree.mods.annotations, baseEnv,
-                        c, tree.pos());
-
-            chk.checkNonCyclicDecl(tree);
-
-            // class type parameters use baseEnv but everything uses env
-            attr.attribTypeVariables(tree.typarams, baseEnv);
-            for (JCTypeParameter tp : tree.typarams)
-                annotate.annotateTypeLater(tp, baseEnv, sym, tree.pos());
-
-            // Add default constructor if needed.
-            if ((c.flags() & INTERFACE) == 0 &&
-                !TreeInfo.hasConstructors(tree.defs)) {
-                List<Type> argtypes = List.nil();
-                List<Type> typarams = List.nil();
-                List<Type> thrown = List.nil();
-                long ctorFlags = 0;
-                boolean based = false;
-                boolean addConstructor = true;
-                JCNewClass nc = null;
-                if (c.name.isEmpty()) {
-                    nc = (JCNewClass)env.next.tree;
-                    if (nc.constructor != null) {
-                        addConstructor = nc.constructor.kind != ERR;
-                        Type superConstrType = types.memberType(c.type,
-                                                                nc.constructor);
-                        argtypes = superConstrType.getParameterTypes();
-                        typarams = superConstrType.getTypeArguments();
-                        ctorFlags = nc.constructor.flags() & VARARGS;
-                        if (nc.encl != null) {
-                            argtypes = argtypes.prepend(nc.encl.type);
-                            based = true;
+            // Enter all member fields and methods of a set of half completed
+            // classes in a second phase.
+            if (wasFirst) {
+                Set<JCCompilationUnit> topLevels = new HashSet<>();
+                try {
+                    while (halfcompleted.nonEmpty()) {
+                        Env<AttrContext> toFinish = halfcompleted.next();
+                        topLevels.add(toFinish.toplevel);
+                        finish(toFinish);
+                        if (allowTypeAnnos) {
+                            typeAnnotations.organizeTypeAnnotationsSignatures(toFinish, (JCClassDecl)toFinish.tree);
+                            typeAnnotations.validateTypeAnnotationsSignatures(toFinish, (JCClassDecl)toFinish.tree);
                         }
-                        thrown = superConstrType.getThrownTypes();
                     }
+                } finally {
+                    isFirst = true;
                 }
-                if (addConstructor) {
-                    MethodSymbol basedConstructor = nc != null ?
-                            (MethodSymbol)nc.constructor : null;
-                    JCTree constrDef = DefaultConstructor(make.at(tree.pos), c,
-                                                        basedConstructor,
-                                                        typarams, argtypes, thrown,
-                                                        ctorFlags, based);
-                    tree.defs = tree.defs.prepend(constrDef);
-                }
-            }
 
-            // enter symbols for 'this' into current scope.
-            VarSymbol thisSym =
-                new VarSymbol(FINAL | HASINIT, names._this, c.type, c);
-            thisSym.pos = Position.FIRSTPOS;
-            env.info.scope.enter(thisSym);
-            // if this is a class, enter symbol for 'super' into current scope.
-            if ((c.flags_field & INTERFACE) == 0 &&
-                    ct.supertype_field.hasTag(CLASS)) {
-                VarSymbol superSym =
-                    new VarSymbol(FINAL | HASINIT, names._super,
-                                  ct.supertype_field, c);
-                superSym.pos = Position.FIRSTPOS;
-                env.info.scope.enter(superSym);
-            }
+                for (JCCompilationUnit toplevel : topLevels) {
+                    chk.checkImportsResolvable(toplevel);
+                }
 
-            // check that no package exists with same fully qualified name,
-            // but admit classes in the unnamed package which have the same
-            // name as a top-level package.
-            if (checkClash &&
-                c.owner.kind == PCK && c.owner != syms.unnamedPackage &&
-                syms.packageExists(c.fullname)) {
-                log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), c);
-            }
-            if (c.owner.kind == PCK && (c.flags_field & PUBLIC) == 0 &&
-                !env.toplevel.sourcefile.isNameCompatible(c.name.toString(),JavaFileObject.Kind.SOURCE)) {
-                c.flags_field |= AUXILIARY;
             }
-        } catch (CompletionFailure ex) {
-            chk.completionError(tree.pos(), ex);
         } finally {
-            deferredLintHandler.setPos(prevLintPos);
-            log.useSource(prev);
-            dependencies.pop();
-        }
-
-        // Enter all member fields and methods of a set of half completed
-        // classes in a second phase.
-        if (wasFirst) {
-            Set<JCCompilationUnit> topLevels = new HashSet<>();
-            try {
-                while (halfcompleted.nonEmpty()) {
-                    Env<AttrContext> toFinish = halfcompleted.next();
-                    topLevels.add(toFinish.toplevel);
-                    finish(toFinish);
-                    if (allowTypeAnnos) {
-                        typeAnnotations.organizeTypeAnnotationsSignatures(toFinish, (JCClassDecl)toFinish.tree);
-                        typeAnnotations.validateTypeAnnotationsSignatures(toFinish, (JCClassDecl)toFinish.tree);
-                    }
-                }
-            } finally {
-                isFirst = true;
-            }
-
-            for (JCCompilationUnit toplevel : topLevels) {
-                chk.checkImportsResolvable(toplevel);
-            }
-
+            annotate.enterDone();
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/FinalStringInNested.java	Fri Oct 24 08:34:51 2014 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8054448
+ * @summary Verify that constant strings in nested classes in anonymous classes
+ *          can be used in annotations.
+ * @compile FinalStringInNested.java
+ */
+
+public class FinalStringInNested {
+
+    public void f() {
+        Object o = new Object() {
+            @FinalStringInNested.Annotation(Nested.ID)
+            class Nested {
+                static final String ID = "B";
+            }
+        };
+    }
+
+    @interface Annotation {
+        String value();
+    }
+}