< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java

Print this page
@@ -413,47 +413,52 @@
          if (env.info.visitingServiceImplementation &&
              env.toplevel.modle == sym.packge().modle) {
              return true;
          }
  
-         switch ((short)(sym.flags() & AccessFlags)) {
-         case PRIVATE:
-             return
-                 (env.enclClass.sym == sym.owner // fast special case
-                  ||
-                  env.enclClass.sym.outermostClass() ==
-                  sym.owner.outermostClass())
-                 &&
-                 sym.isInheritedIn(site.tsym, types);
-         case 0:
-             return
-                 (env.toplevel.packge == sym.owner.owner // fast special case
-                  ||
-                  env.toplevel.packge == sym.packge())
-                 &&
-                 isAccessible(env, site, checkInner)
-                 &&
-                 sym.isInheritedIn(site.tsym, types)
-                 &&
-                 notOverriddenIn(site, sym);
-         case PROTECTED:
-             return
-                 (env.toplevel.packge == sym.owner.owner // fast special case
-                  ||
-                  env.toplevel.packge == sym.packge()
-                  ||
-                  isProtectedAccessible(sym, env.enclClass.sym, site)
-                  ||
-                  // OK to select instance method or field from 'super' or type name
-                  // (but type names should be disallowed elsewhere!)
-                  env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP)
-                 &&
-                 isAccessible(env, site, checkInner)
-                 &&
-                 notOverriddenIn(site, sym);
-         default: // this case includes erroneous combinations as well
-             return isAccessible(env, site, checkInner) && notOverriddenIn(site, sym);
+         ClassSymbol enclosingCsym = env.enclClass.sym;
+         try {
+             switch ((short)(sym.flags() & AccessFlags)) {
+                 case PRIVATE:
+                     return
+                             (env.enclClass.sym == sym.owner // fast special case
+                                     ||
+                                     env.enclClass.sym.outermostClass() ==
+                                             sym.owner.outermostClass())
+                                     &&
+                                     sym.isInheritedIn(site.tsym, types);
+                 case 0:
+                     return
+                             (env.toplevel.packge == sym.owner.owner // fast special case
+                                     ||
+                                     env.toplevel.packge == sym.packge())
+                                     &&
+                                     isAccessible(env, site, checkInner)
+                                     &&
+                                     sym.isInheritedIn(site.tsym, types)
+                                     &&
+                                     notOverriddenIn(site, sym);
+                 case PROTECTED:
+                     return
+                             (env.toplevel.packge == sym.owner.owner // fast special case
+                                     ||
+                                     env.toplevel.packge == sym.packge()
+                                     ||
+                                     isProtectedAccessible(sym, env.enclClass.sym, site)
+                                     ||
+                                     // OK to select instance method or field from 'super' or type name
+                                     // (but type names should be disallowed elsewhere!)
+                                     env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP)
+                                     &&
+                                     isAccessible(env, site, checkInner)
+                                     &&
+                                     notOverriddenIn(site, sym);
+                 default: // this case includes erroneous combinations as well
+                     return isAccessible(env, site, checkInner) && notOverriddenIn(site, sym);
+             }
+         } finally {
+             env.enclClass.sym = enclosingCsym;
          }
      }
      //where
      /* `sym' is accessible only if not overridden by
       * another symbol which is a member of `site'

@@ -1501,17 +1506,22 @@
              if (isStatic(env1)) staticOnly = true;
              if (sym == null) {
                  sym = findField(env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
              }
              if (sym.exists()) {
-                 if (staticOnly &&
-                         sym.kind == VAR &&
+                 if (sym.kind == VAR &&
                          sym.owner.kind == TYP &&
-                         (sym.flags() & STATIC) == 0)
-                     return new StaticError(sym);
-                 else
-                     return sym;
+                         (sym.flags() & STATIC) == 0) {
+                     if (staticOnly)
+                         return new StaticError(sym);
+                     if (env1.info.ctorPrologue && (sym.flags_field & SYNTHETIC) == 0) {
+                         if (!env.tree.hasTag(ASSIGN) || !TreeInfo.isIdentOrThisDotIdent(((JCAssign)env.tree).lhs)) {
+                             return new RefBeforeCtorCalledError(sym);
+                         }
+                     }
+                 }
+                 return sym;
              } else {
                  bestSoFar = bestOf(bestSoFar, sym);
              }
  
              if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;

@@ -2004,15 +2014,19 @@
              try {
                  Symbol sym = findMethod(
                      env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
                      allowBoxing, useVarargs);
                  if (sym.exists()) {
-                     if (staticOnly &&
-                         sym.kind == MTH &&
-                         sym.owner.kind == TYP &&
-                         (sym.flags() & STATIC) == 0) return new StaticError(sym);
-                     else return sym;
+                     if (sym.kind == MTH &&
+                             sym.owner.kind == TYP &&
+                             (sym.flags() & STATIC) == 0) {
+                         if (staticOnly)
+                             return new StaticError(sym);
+                         if (env1.info.ctorPrologue && env1 == env)
+                             return new RefBeforeCtorCalledError(sym);
+                     }
+                     return sym;
                  } else {
                      bestSoFar = bestOf(bestSoFar, sym);
                  }
              } finally {
                  env1.info.preferredTreeForDiagnostics = null;

@@ -3765,11 +3779,14 @@
          while (env1.outer != null) {
              if (isStatic(env1)) staticOnly = true;
              if (env1.enclClass.sym == c) {
                  Symbol sym = env1.info.scope.findFirst(name);
                  if (sym != null) {
-                     if (staticOnly) sym = new StaticError(sym);
+                     if (staticOnly)
+                         sym = new StaticError(sym);
+                     else if (env1.info.ctorPrologue)
+                         sym = new RefBeforeCtorCalledError(sym);
                      return accessBase(sym, pos, env.enclClass.sym.type,
                                    name, true);
                  }
              }
              if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;

@@ -3779,10 +3796,12 @@
              name == names._super && !isStatic(env) &&
              types.isDirectSuperInterface(c, env.enclClass.sym)) {
              //this might be a default super call if one of the superinterfaces is 'c'
              for (Type t : pruneInterfaces(env.enclClass.type)) {
                  if (t.tsym == c) {
+                     if (env.info.ctorPrologue)
+                         log.error(pos, Errors.CantRefBeforeCtorCalled(name));
                      env.info.defaultSuperCallSite = t;
                      return new VarSymbol(0, names._super,
                              types.asSuper(env.enclClass.type, c), env.enclClass.sym);
                  }
              }

@@ -3880,12 +3899,12 @@
  
      Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t, boolean isSuperCall) {
          Type thisType = (t.tsym.owner.kind.matches(KindSelector.VAL_MTH)
                           ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this)
                           : resolveSelfContaining(pos, env, t.tsym, isSuperCall)).type;
-         if (env.info.isSelfCall && thisType.tsym == env.enclClass.sym) {
-             log.error(pos, Errors.CantRefBeforeCtorCalled("this"));
+         if (env.info.ctorPrologue && thisType.tsym == env.enclClass.sym) {
+             log.error(pos, Errors.CantRefBeforeCtorCalled(names._this));
          }
          return thisType;
      }
  
  /* ***************************************************************************

@@ -4194,11 +4213,10 @@
                      return diags.create(dkind, log.currentSource(), pos,
                                "cant.apply.symbol.noargs",
                                rewriter,
                                kindName(ws),
                                ws.name == names.init ? ws.owner.name : ws.name,
-                               kindName(ws.owner),
                                ws.owner.type,
                                c.snd);
                  default:
                      // Avoid saying "constructor Array in class Array"
                      if (ws.owner == syms.arrayClass && ws.name == names.init) {

@@ -4586,11 +4604,15 @@
       * has erroneously been accessed from a static context.
       */
      class StaticError extends InvalidSymbolError {
  
          StaticError(Symbol sym) {
-             super(STATICERR, sym, "static error");
+             this(sym, "static error");
+         }
+ 
+         StaticError(Symbol sym, String debugName) {
+             super(STATICERR, sym, debugName);
          }
  
          @Override
          JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
                  DiagnosticPosition pos,

@@ -4605,10 +4627,36 @@
              return diags.create(dkind, log.currentSource(), pos,
                      "non-static.cant.be.ref", kindName(sym), errSym);
          }
      }
  
+     /**
+      * Specialization of {@link InvalidSymbolError} for illegal
+      * early accesses within a constructor prologue.
+      */
+     class RefBeforeCtorCalledError extends StaticError {
+ 
+         RefBeforeCtorCalledError(Symbol sym) {
+             super(sym, "prologue error");
+         }
+ 
+         @Override
+         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
+                 DiagnosticPosition pos,
+                 Symbol location,
+                 Type site,
+                 Name name,
+                 List<Type> argtypes,
+                 List<Type> typeargtypes) {
+             Symbol errSym = ((sym.kind == TYP && sym.type.hasTag(CLASS))
+                 ? types.erasure(sym.type).tsym
+                 : sym);
+             return diags.create(dkind, log.currentSource(), pos,
+                     "cant.ref.before.ctor.called", errSym);
+         }
+     }
+ 
      /**
       * InvalidSymbolError error class indicating that a pair of symbols
       * (either methods, constructors or operands) are ambiguous
       * given an actual arguments/type argument list.
       */

@@ -4718,11 +4766,11 @@
      class BadMethodReferenceError extends StaticError {
  
          boolean unboundLookup;
  
          public BadMethodReferenceError(Symbol sym, boolean unboundLookup) {
-             super(sym);
+             super(sym, "bad method ref error");
              this.unboundLookup = unboundLookup;
          }
  
          @Override
          JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
< prev index next >