< prev index next >

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

Print this page

 107     final DeferredAttr deferredAttr;
 108     final Check chk;
 109     final Flow flow;
 110     final MemberEnter memberEnter;
 111     final TypeEnter typeEnter;
 112     final TreeMaker make;
 113     final ConstFold cfolder;
 114     final Enter enter;
 115     final Target target;
 116     final Types types;
 117     final Preview preview;
 118     final JCDiagnostic.Factory diags;
 119     final TypeAnnotations typeAnnotations;
 120     final DeferredLintHandler deferredLintHandler;
 121     final TypeEnvs typeEnvs;
 122     final Dependencies dependencies;
 123     final Annotate annotate;
 124     final ArgumentAttr argumentAttr;
 125     final MatchBindingsComputer matchBindingsComputer;
 126     final AttrRecover attrRecover;

 127 
 128     public static Attr instance(Context context) {
 129         Attr instance = context.get(attrKey);
 130         if (instance == null)
 131             instance = new Attr(context);
 132         return instance;
 133     }
 134 
 135     @SuppressWarnings("this-escape")
 136     protected Attr(Context context) {
 137         context.put(attrKey, this);
 138 
 139         names = Names.instance(context);
 140         log = Log.instance(context);
 141         syms = Symtab.instance(context);
 142         rs = Resolve.instance(context);
 143         operators = Operators.instance(context);
 144         chk = Check.instance(context);
 145         flow = Flow.instance(context);
 146         memberEnter = MemberEnter.instance(context);
 147         typeEnter = TypeEnter.instance(context);
 148         make = TreeMaker.instance(context);
 149         enter = Enter.instance(context);
 150         infer = Infer.instance(context);
 151         analyzer = Analyzer.instance(context);
 152         deferredAttr = DeferredAttr.instance(context);
 153         cfolder = ConstFold.instance(context);
 154         target = Target.instance(context);
 155         types = Types.instance(context);
 156         preview = Preview.instance(context);
 157         diags = JCDiagnostic.Factory.instance(context);
 158         annotate = Annotate.instance(context);
 159         typeAnnotations = TypeAnnotations.instance(context);
 160         deferredLintHandler = DeferredLintHandler.instance(context);
 161         typeEnvs = TypeEnvs.instance(context);
 162         dependencies = Dependencies.instance(context);
 163         argumentAttr = ArgumentAttr.instance(context);
 164         matchBindingsComputer = MatchBindingsComputer.instance(context);
 165         attrRecover = AttrRecover.instance(context);

 166 
 167         Options options = Options.instance(context);
 168 
 169         Source source = Source.instance(context);
 170         allowReifiableTypesInInstanceof = Feature.REIFIABLE_TYPES_INSTANCEOF.allowedInSource(source);
 171         allowRecords = Feature.RECORDS.allowedInSource(source);
 172         allowPatternSwitch = (preview.isEnabled() || !preview.isPreview(Feature.PATTERN_SWITCH)) &&
 173                              Feature.PATTERN_SWITCH.allowedInSource(source);
 174         allowUnconditionalPatternsInstanceOf =
 175                              Feature.UNCONDITIONAL_PATTERN_IN_INSTANCEOF.allowedInSource(source);
 176         sourceName = source.name;
 177         useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning");
 178 
 179         statInfo = new ResultInfo(KindSelector.NIL, Type.noType);
 180         varAssignmentInfo = new ResultInfo(KindSelector.ASG, Type.noType);
 181         unknownExprInfo = new ResultInfo(KindSelector.VAL, Type.noType);
 182         methodAttrInfo = new MethodAttrInfo();
 183         unknownTypeInfo = new ResultInfo(KindSelector.TYP, Type.noType);
 184         unknownTypeExprInfo = new ResultInfo(KindSelector.VAL_TYP, Type.noType);
 185         recoveryInfo = new RecoveryInfo(deferredAttr.emptyDeferredAttrContext);
 186         initBlockType = new MethodType(List.nil(), syms.voidType, List.nil(), syms.methodClass);


 187     }
 188 
 189     /** Switch: reifiable types in instanceof enabled?
 190      */
 191     boolean allowReifiableTypesInInstanceof;
 192 
 193     /** Are records allowed
 194      */
 195     private final boolean allowRecords;
 196 
 197     /** Are patterns in switch allowed
 198      */
 199     private final boolean allowPatternSwitch;
 200 
 201     /** Are unconditional patterns in instanceof allowed
 202      */
 203     private final boolean allowUnconditionalPatternsInstanceOf;
 204 




 205     /**
 206      * Switch: warn about use of variable before declaration?
 207      * RFE: 6425594
 208      */
 209     boolean useBeforeDeclarationWarning;
 210 
 211     /**
 212      * Switch: name of source level; used for error reporting.
 213      */
 214     String sourceName;
 215 
 216     /** Check kind and type of given tree against protokind and prototype.
 217      *  If check succeeds, store type in tree and return it.
 218      *  If check fails, store errType in tree and return it.
 219      *  No checks are performed if the prototype is a method type.
 220      *  It is not necessary in this case since we know that kind and type
 221      *  are correct.
 222      *
 223      *  @param tree     The tree whose kind and type is checked
 224      *  @param found    The computed type of the tree

 278               owner.kind == VAR ||           // i.e. we are in a variable initializer
 279               (owner.flags() & BLOCK) != 0)  // i.e. we are in an initializer block
 280              &&
 281              v.owner == owner.owner
 282              &&
 283              ((v.flags() & STATIC) != 0) == Resolve.isStatic(env));
 284         boolean insideCompactConstructor = env.enclMethod != null && TreeInfo.isCompactConstructor(env.enclMethod);
 285         return isAssignable & !insideCompactConstructor;
 286     }
 287 
 288     /** Check that variable can be assigned to.
 289      *  @param pos    The current source code position.
 290      *  @param v      The assigned variable
 291      *  @param base   If the variable is referred to in a Select, the part
 292      *                to the left of the `.', null otherwise.
 293      *  @param env    The current environment.
 294      */
 295     void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, Env<AttrContext> env) {
 296         if (v.name == names._this) {
 297             log.error(pos, Errors.CantAssignValToThis);
 298             return;
 299         }
 300         if ((v.flags() & FINAL) != 0 &&
 301             ((v.flags() & HASINIT) != 0
 302              ||
 303              !((base == null ||
 304                TreeInfo.isThisQualifier(base)) &&
 305                isAssignableAsBlankFinal(v, env)))) {
 306             if (v.isResourceVariable()) { //TWR resource
 307                 log.error(pos, Errors.TryResourceMayNotBeAssigned(v));
 308             } else {
 309                 log.error(pos, Errors.CantAssignValToVar(Flags.toSource(v.flags() & (STATIC | FINAL)), v));
 310             }
 311             return;
 312         }
 313 
 314         // Check instance field assignments that appear in constructor prologues
 315         if (rs.isEarlyReference(env, base, v)) {
 316 
 317             // Field may not be inherited from a superclass
 318             if (v.owner != env.enclClass.sym) {
 319                 log.error(pos, Errors.CantRefBeforeCtorCalled(v));
 320                 return;
 321             }
 322 
 323             // Field may not have an initializer
 324             if ((v.flags() & HASINIT) != 0) {
 325                 log.error(pos, Errors.CantAssignInitializedBeforeCtorCalled(v));
 326                 return;
 327             }
 328         }
 329     }
 330 
 331     /** Does tree represent a static reference to an identifier?
 332      *  It is assumed that tree is either a SELECT or an IDENT.
 333      *  We have to weed out selects from non-type names here.
 334      *  @param tree    The candidate tree.
 335      */
 336     boolean isStaticReference(JCTree tree) {
 337         if (tree.hasTag(SELECT)) {
 338             Symbol lsym = TreeInfo.symbol(((JCFieldAccess) tree).selected);
 339             if (lsym == null || lsym.kind != TYP) {
 340                 return false;
 341             }
 342         }
 343         return true;
 344     }
 345 
 346     /** Is this symbol a type?
 347      */

1105                          *     - have an accessibility stricter than that of the record type
1106                          *     - explicitly invoke any other constructor
1107                          */
1108                         if ((tree.sym.flags_field & GENERATEDCONSTR) == 0) {
1109                             if (Check.protection(m.flags()) > Check.protection(env.enclClass.sym.flags())) {
1110                                 log.error(tree,
1111                                         (env.enclClass.sym.flags() & AccessFlags) == 0 ?
1112                                             Errors.InvalidCanonicalConstructorInRecord(
1113                                                 Fragments.Canonical,
1114                                                 env.enclClass.sym.name,
1115                                                 Fragments.CanonicalMustNotHaveStrongerAccess("package")
1116                                             ) :
1117                                             Errors.InvalidCanonicalConstructorInRecord(
1118                                                     Fragments.Canonical,
1119                                                     env.enclClass.sym.name,
1120                                                     Fragments.CanonicalMustNotHaveStrongerAccess(asFlagSet(env.enclClass.sym.flags() & AccessFlags))
1121                                             )
1122                                 );
1123                             }
1124 
1125                             if (TreeInfo.hasAnyConstructorCall(tree)) {
1126                                 log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1127                                         Fragments.Canonical, env.enclClass.sym.name,
1128                                         Fragments.CanonicalMustNotContainExplicitConstructorInvocation));
1129                             }
1130                         }
1131 
1132                         // also we want to check that no type variables have been defined
1133                         if (!tree.typarams.isEmpty()) {
1134                             log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1135                                     Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalMustNotDeclareTypeVariables));
1136                         }
1137 
1138                         /* and now we need to check that the constructor's arguments are exactly the same as those of the
1139                          * record components
1140                          */
1141                         List<? extends RecordComponent> recordComponents = env.enclClass.sym.getRecordComponents();
1142                         List<Type> recordFieldTypes = TreeInfo.recordFields(env.enclClass).map(vd -> vd.sym.type);
1143                         for (JCVariableDecl param: tree.params) {
1144                             boolean paramIsVarArgs = (param.sym.flags_field & VARARGS) != 0;
1145                             if (!types.isSameType(param.type, recordFieldTypes.head) ||

1187                 }
1188                 if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0)
1189                     log.error(tree.pos(), Errors.MissingMethBodyOrDeclAbstract);
1190             } else {
1191                 if ((tree.sym.flags() & (ABSTRACT|DEFAULT|PRIVATE)) == ABSTRACT) {
1192                     if ((owner.flags() & INTERFACE) != 0) {
1193                         log.error(tree.body.pos(), Errors.IntfMethCantHaveBody);
1194                     } else {
1195                         log.error(tree.pos(), Errors.AbstractMethCantHaveBody);
1196                     }
1197                 } else if ((tree.mods.flags & NATIVE) != 0) {
1198                     log.error(tree.pos(), Errors.NativeMethCantHaveBody);
1199                 }
1200                 // Add an implicit super() call unless an explicit call to
1201                 // super(...) or this(...) is given
1202                 // or we are compiling class java.lang.Object.
1203                 if (isConstructor && owner.type != syms.objectType) {
1204                     if (!TreeInfo.hasAnyConstructorCall(tree)) {
1205                         JCStatement supCall = make.at(tree.body.pos).Exec(make.Apply(List.nil(),
1206                                 make.Ident(names._super), make.Idents(List.nil())));
1207                         tree.body.stats = tree.body.stats.prepend(supCall);




1208                     } else if ((env.enclClass.sym.flags() & ENUM) != 0 &&
1209                             (tree.mods.flags & GENERATEDCONSTR) == 0 &&
1210                             TreeInfo.hasConstructorCall(tree, names._super)) {
1211                         // enum constructors are not allowed to call super
1212                         // directly, so make sure there aren't any super calls
1213                         // in enum constructors, except in the compiler
1214                         // generated one.
1215                         log.error(tree.body.stats.head.pos(),
1216                                   Errors.CallToSuperNotAllowedInEnumCtor(env.enclClass.sym));
1217                     }
1218                     if (env.enclClass.sym.isRecord() && (tree.sym.flags_field & RECORD) != 0) { // we are seeing the canonical constructor
1219                         List<Name> recordComponentNames = TreeInfo.recordFields(env.enclClass).map(vd -> vd.sym.name);
1220                         List<Name> initParamNames = tree.sym.params.map(p -> p.name);
1221                         if (!initParamNames.equals(recordComponentNames)) {
1222                             log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1223                                     Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalWithNameMismatch));
1224                         }
1225                         if (tree.sym.type.asMethodType().thrown != null && !tree.sym.type.asMethodType().thrown.isEmpty()) {
1226                             log.error(tree,
1227                                     Errors.InvalidCanonicalConstructorInRecord(
1228                                             TreeInfo.isCompactConstructor(tree) ? Fragments.Compact : Fragments.Canonical,
1229                                             env.enclClass.sym.name,
1230                                             Fragments.ThrowsClauseNotAllowedForCanonicalConstructor(
1231                                                     TreeInfo.isCompactConstructor(tree) ? Fragments.Compact : Fragments.Canonical)));
1232                         }
1233                     }
1234                 }
1235 
1236                 // Attribute all type annotations in the body
1237                 annotate.queueScanTreeAndTypeAnnotate(tree.body, localEnv, m, null);
1238                 annotate.flush();
1239 
1240                 // Start of constructor prologue
1241                 localEnv.info.ctorPrologue = isConstructor;
1242 
1243                 // Attribute method body.
1244                 attribStat(tree.body, localEnv);



















1245             }
1246 
1247             localEnv.info.scope.leave();
1248             result = tree.type = m.type;
1249         } finally {
1250             chk.setLint(prevLint);
1251             chk.setMethod(prevMethod);
1252             env.info.ctorPrologue = ctorProloguePrev;
1253         }
1254     }
1255 

















































































































































































































































1256     public void visitVarDef(JCVariableDecl tree) {
1257         // Local variables have not been entered yet, so we need to do it now:
1258         if (env.info.scope.owner.kind == MTH || env.info.scope.owner.kind == VAR) {
1259             if (tree.sym != null) {
1260                 // parameters have already been entered
1261                 env.info.scope.enter(tree.sym);
1262             } else {
1263                 if (tree.isImplicitlyTyped() && (tree.getModifiers().flags & PARAMETER) == 0) {
1264                     if (tree.init == null) {
1265                         //cannot use 'var' without initializer
1266                         log.error(tree, Errors.CantInferLocalVarType(tree.name, Fragments.LocalMissingInit));
1267                         tree.vartype = make.Erroneous();
1268                     } else {
1269                         Fragment msg = canInferLocalVarType(tree);
1270                         if (msg != null) {
1271                             //cannot use 'var' with initializer which require an explicit target
1272                             //(e.g. lambda, method reference, array initializer).
1273                             log.error(tree, Errors.CantInferLocalVarType(tree.name, msg));
1274                             tree.vartype = make.Erroneous();
1275                         }

1297         chk.validate(tree.vartype, env, !isImplicitLambdaParameter && !tree.isImplicitlyTyped());
1298 
1299         try {
1300             v.getConstValue(); // ensure compile-time constant initializer is evaluated
1301             deferredLintHandler.flush(tree, lint);
1302             chk.checkDeprecatedAnnotation(tree.pos(), v);
1303 
1304             if (tree.init != null) {
1305                 if ((v.flags_field & FINAL) == 0 ||
1306                     !memberEnter.needsLazyConstValue(tree.init)) {
1307                     // Not a compile-time constant
1308                     // Attribute initializer in a new environment
1309                     // with the declared variable as owner.
1310                     // Check that initializer conforms to variable's declared type.
1311                     Env<AttrContext> initEnv = memberEnter.initEnv(tree, env);
1312                     initEnv.info.lint = lint;
1313                     // In order to catch self-references, we set the variable's
1314                     // declaration position to maximal possible value, effectively
1315                     // marking the variable as undefined.
1316                     initEnv.info.enclVar = v;
1317                     attribExpr(tree.init, initEnv, v.type);
1318                     if (tree.isImplicitlyTyped()) {
1319                         //fixup local variable type
1320                         v.type = chk.checkLocalVarType(tree, tree.init.type, tree.name);














1321                     }
1322                 }
1323                 if (tree.isImplicitlyTyped()) {
1324                     setSyntheticVariableType(tree, v.type);
1325                 }
1326             }
1327             result = tree.type = v.type;
1328             if (env.enclClass.sym.isRecord() && tree.sym.owner.kind == TYP && !v.isStatic()) {
1329                 if (isNonArgsMethodInObject(v.name)) {
1330                     log.error(tree, Errors.IllegalRecordComponentName(v));
1331                 }
1332             }
1333             chk.checkRequiresIdentity(tree, env.info.lint);
1334         }
1335         finally {
1336             chk.setLint(prevLint);
1337         }
1338     }
1339 
1340     private void doQueueScanTreeAndTypeAnnotateForVarInit(JCVariableDecl tree, Env<AttrContext> env) {

1421             }
1422         }
1423     }
1424 
1425     public void visitSkip(JCSkip tree) {
1426         result = null;
1427     }
1428 
1429     public void visitBlock(JCBlock tree) {
1430         if (env.info.scope.owner.kind == TYP || env.info.scope.owner.kind == ERR) {
1431             // Block is a static or instance initializer;
1432             // let the owner of the environment be a freshly
1433             // created BLOCK-method.
1434             Symbol fakeOwner =
1435                 new MethodSymbol(tree.flags | BLOCK |
1436                     env.info.scope.owner.flags() & STRICTFP, names.empty, initBlockType,
1437                     env.info.scope.owner);
1438             final Env<AttrContext> localEnv =
1439                 env.dup(tree, env.info.dup(env.info.scope.dupUnshared(fakeOwner)));
1440 
1441             if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;




1442             // Attribute all type annotations in the block
1443             annotate.queueScanTreeAndTypeAnnotate(tree, localEnv, localEnv.info.scope.owner, null);
1444             annotate.flush();
1445             attribStats(tree.stats, localEnv);
1446 
1447             {
1448                 // Store init and clinit type annotations with the ClassSymbol
1449                 // to allow output in Gen.normalizeDefs.
1450                 ClassSymbol cs = (ClassSymbol)env.info.scope.owner;
1451                 List<Attribute.TypeCompound> tas = localEnv.info.scope.owner.getRawTypeAttributes();
1452                 if ((tree.flags & STATIC) != 0) {
1453                     cs.appendClassInitTypeAttributes(tas);
1454                 } else {
1455                     cs.appendInitTypeAttributes(tas);
1456                 }
1457             }
1458         } else {
1459             // Create a new local environment with a local scope.
1460             Env<AttrContext> localEnv =
1461                 env.dup(tree, env.info.dup(env.info.scope.dup()));

1934     // where
1935     /** Return the selected enumeration constant symbol, or null. */
1936     private Symbol enumConstant(JCTree tree, Type enumType) {
1937         if (tree.hasTag(IDENT)) {
1938             JCIdent ident = (JCIdent)tree;
1939             Name name = ident.name;
1940             for (Symbol sym : enumType.tsym.members().getSymbolsByName(name)) {
1941                 if (sym.kind == VAR) {
1942                     Symbol s = ident.sym = sym;
1943                     ((VarSymbol)s).getConstValue(); // ensure initializer is evaluated
1944                     ident.type = s.type;
1945                     return ((s.flags_field & Flags.ENUM) == 0)
1946                         ? null : s;
1947                 }
1948             }
1949         }
1950         return null;
1951     }
1952 
1953     public void visitSynchronized(JCSynchronized tree) {
1954         chk.checkRefType(tree.pos(), attribExpr(tree.lock, env));
1955         if (tree.lock.type != null && tree.lock.type.isValueBased()) {
1956             env.info.lint.logIfEnabled(tree.pos(), LintWarnings.AttemptToSynchronizeOnInstanceOfValueBasedClass);
1957         }
1958         attribStat(tree.body, env);
1959         result = null;
1960     }
1961 
1962     public void visitTry(JCTry tree) {
1963         // Create a new local environment with a local
1964         Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
1965         try {
1966             boolean isTryWithResource = tree.resources.nonEmpty();
1967             // Create a nested environment for attributing the try block if needed
1968             Env<AttrContext> tryEnv = isTryWithResource ?
1969                 env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) :
1970                 localEnv;
1971             try {
1972                 // Attribute resource declarations
1973                 for (JCTree resource : tree.resources) {
1974                     CheckContext twrContext = new Check.NestedCheckContext(resultInfo.checkContext) {
1975                         @Override

4389     }
4390 
4391     public void visitSelect(JCFieldAccess tree) {
4392         // Determine the expected kind of the qualifier expression.
4393         KindSelector skind = KindSelector.NIL;
4394         if (tree.name == names._this || tree.name == names._super ||
4395                 tree.name == names._class)
4396         {
4397             skind = KindSelector.TYP;
4398         } else {
4399             if (pkind().contains(KindSelector.PCK))
4400                 skind = KindSelector.of(skind, KindSelector.PCK);
4401             if (pkind().contains(KindSelector.TYP))
4402                 skind = KindSelector.of(skind, KindSelector.TYP, KindSelector.PCK);
4403             if (pkind().contains(KindSelector.VAL_MTH))
4404                 skind = KindSelector.of(skind, KindSelector.VAL, KindSelector.TYP);
4405         }
4406 
4407         // Attribute the qualifier expression, and determine its symbol (if any).
4408         Type site = attribTree(tree.selected, env, new ResultInfo(skind, Type.noType));

4409         if (!pkind().contains(KindSelector.TYP_PCK))
4410             site = capture(site); // Capture field access
4411 
4412         // don't allow T.class T[].class, etc
4413         if (skind == KindSelector.TYP) {
4414             Type elt = site;
4415             while (elt.hasTag(ARRAY))
4416                 elt = ((ArrayType)elt).elemtype;
4417             if (elt.hasTag(TYPEVAR)) {
4418                 log.error(tree.pos(), Errors.TypeVarCantBeDeref);
4419                 result = tree.type = types.createErrorType(tree.name, site.tsym, site);
4420                 tree.sym = tree.type.tsym;
4421                 return ;
4422             }
4423         }
4424 
4425         // If qualifier symbol is a type or `super', assert `selectSuper'
4426         // for the selection. This is relevant for determining whether
4427         // protected symbols are accessible.
4428         Symbol sitesym = TreeInfo.symbol(tree.selected);

5492                                                       .filter(s -> s.tsym.isSealed())
5493                                                       .map(s -> (ClassSymbol) s.tsym)
5494                                                       .collect(List.collector());
5495 
5496                 if (sealedSupers.isEmpty()) {
5497                     if ((c.flags_field & Flags.NON_SEALED) != 0) {
5498                         boolean hasErrorSuper = false;
5499 
5500                         hasErrorSuper |= types.directSupertypes(c.type)
5501                                               .stream()
5502                                               .anyMatch(s -> s.tsym.kind == Kind.ERR);
5503 
5504                         ClassType ct = (ClassType) c.type;
5505 
5506                         hasErrorSuper |= !ct.isCompound() && ct.interfaces_field != ct.all_interfaces_field;
5507 
5508                         if (!hasErrorSuper) {
5509                             log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.NonSealedWithNoSealedSupertype(c));
5510                         }
5511                     }
5512                 } else {
5513                     if (c.isDirectlyOrIndirectlyLocal() && !c.isEnum()) {
5514                         log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.LocalClassesCantExtendSealed(c.isAnonymous() ? Fragments.Anonymous : Fragments.Local));
5515                     }
5516 
5517                     if (!c.type.isCompound()) {
5518                         for (ClassSymbol supertypeSym : sealedSupers) {
5519                             if (!supertypeSym.isPermittedSubclass(c.type.tsym)) {
5520                                 log.error(TreeInfo.diagnosticPositionFor(c.type.tsym, env.tree), Errors.CantInheritFromSealed(supertypeSym));
5521                             }
5522                         }
5523                         if (!c.isNonSealed() && !c.isFinal() && !c.isSealed()) {
5524                             log.error(TreeInfo.diagnosticPositionFor(c, env.tree),
5525                                     c.isInterface() ?
5526                                             Errors.NonSealedOrSealedExpected :
5527                                             Errors.NonSealedSealedOrFinalExpected);
5528                         }
5529                     }
5530                 }
5531 
5532                 deferredLintHandler.flush(env.tree, env.info.lint);
5533                 env.info.returnResult = null;
5534                 // java.lang.Enum may not be subclassed by a non-enum
5535                 if (st.tsym == syms.enumSym &&
5536                     ((c.flags_field & (Flags.ENUM|Flags.COMPOUND)) == 0))
5537                     log.error(env.tree.pos(), Errors.EnumNoSubclassing);
5538 
5539                 // Enums may not be extended by source-level classes
5540                 if (st.tsym != null &&
5541                     ((st.tsym.flags_field & Flags.ENUM) != 0) &&
5542                     ((c.flags_field & (Flags.ENUM | Flags.COMPOUND)) == 0)) {
5543                     log.error(env.tree.pos(), Errors.EnumTypesNotExtensible);
5544                 }
5545 
5546                 if (rs.isSerializable(c.type)) {
5547                     env.info.isSerializable = true;
5548                 }
5549 





5550                 attribClassBody(env, c);
5551 
5552                 chk.checkDeprecatedAnnotation(env.tree.pos(), c);
5553                 chk.checkClassOverrideEqualsAndHashIfNeeded(env.tree.pos(), c);
5554                 chk.checkFunctionalInterface((JCClassDecl) env.tree, c);
5555                 chk.checkLeaksNotAccessible(env, (JCClassDecl) env.tree);
5556 
5557                 if (c.isImplicit()) {
5558                     chk.checkHasMain(env.tree.pos(), c);
5559                 }
5560             } finally {
5561                 env.info.returnResult = prevReturnRes;
5562                 log.useSource(prev);
5563                 chk.setLint(prevLint);
5564             }
5565 
5566         }
5567     }
5568 
5569     public void visitImport(JCImport tree) {

5674                         sym.kind != VAR ||
5675                         sym.getConstValue() == null)
5676                     log.error(l.head.pos(), Errors.IclsCantHaveStaticDecl(c));
5677             }
5678         }
5679 
5680         // Check for proper placement of super()/this() calls.
5681         chk.checkSuperInitCalls(tree);
5682 
5683         // Check for cycles among non-initial constructors.
5684         chk.checkCyclicConstructors(tree);
5685 
5686         // Check for cycles among annotation elements.
5687         chk.checkNonCyclicElements(tree);
5688 
5689         // Check for proper use of serialVersionUID and other
5690         // serialization-related fields and methods
5691         if (env.info.lint.isEnabled(LintCategory.SERIAL)
5692                 && rs.isSerializable(c.type)
5693                 && !c.isAnonymous()) {
5694             chk.checkSerialStructure(tree, c);
5695         }
5696         // Correctly organize the positions of the type annotations
5697         typeAnnotations.organizeTypeAnnotationsBodies(tree);
5698 
5699         // Check type annotations applicability rules
5700         validateTypeAnnotations(tree, false);
5701     }
5702         // where
5703         /** get a diagnostic position for an attribute of Type t, or null if attribute missing */
5704         private DiagnosticPosition getDiagnosticPosition(JCClassDecl tree, Type t) {
5705             for(List<JCAnnotation> al = tree.mods.annotations; !al.isEmpty(); al = al.tail) {
5706                 if (types.isSameType(al.head.annotationType.type, t))
5707                     return al.head.pos();
5708             }
5709 
5710             return null;
5711         }
5712 
5713     private Type capture(Type type) {
5714         return types.capture(type);

 107     final DeferredAttr deferredAttr;
 108     final Check chk;
 109     final Flow flow;
 110     final MemberEnter memberEnter;
 111     final TypeEnter typeEnter;
 112     final TreeMaker make;
 113     final ConstFold cfolder;
 114     final Enter enter;
 115     final Target target;
 116     final Types types;
 117     final Preview preview;
 118     final JCDiagnostic.Factory diags;
 119     final TypeAnnotations typeAnnotations;
 120     final DeferredLintHandler deferredLintHandler;
 121     final TypeEnvs typeEnvs;
 122     final Dependencies dependencies;
 123     final Annotate annotate;
 124     final ArgumentAttr argumentAttr;
 125     final MatchBindingsComputer matchBindingsComputer;
 126     final AttrRecover attrRecover;
 127     final LocalProxyVarsGen localProxyVarsGen;
 128 
 129     public static Attr instance(Context context) {
 130         Attr instance = context.get(attrKey);
 131         if (instance == null)
 132             instance = new Attr(context);
 133         return instance;
 134     }
 135 
 136     @SuppressWarnings("this-escape")
 137     protected Attr(Context context) {
 138         context.put(attrKey, this);
 139 
 140         names = Names.instance(context);
 141         log = Log.instance(context);
 142         syms = Symtab.instance(context);
 143         rs = Resolve.instance(context);
 144         operators = Operators.instance(context);
 145         chk = Check.instance(context);
 146         flow = Flow.instance(context);
 147         memberEnter = MemberEnter.instance(context);
 148         typeEnter = TypeEnter.instance(context);
 149         make = TreeMaker.instance(context);
 150         enter = Enter.instance(context);
 151         infer = Infer.instance(context);
 152         analyzer = Analyzer.instance(context);
 153         deferredAttr = DeferredAttr.instance(context);
 154         cfolder = ConstFold.instance(context);
 155         target = Target.instance(context);
 156         types = Types.instance(context);
 157         preview = Preview.instance(context);
 158         diags = JCDiagnostic.Factory.instance(context);
 159         annotate = Annotate.instance(context);
 160         typeAnnotations = TypeAnnotations.instance(context);
 161         deferredLintHandler = DeferredLintHandler.instance(context);
 162         typeEnvs = TypeEnvs.instance(context);
 163         dependencies = Dependencies.instance(context);
 164         argumentAttr = ArgumentAttr.instance(context);
 165         matchBindingsComputer = MatchBindingsComputer.instance(context);
 166         attrRecover = AttrRecover.instance(context);
 167         localProxyVarsGen = LocalProxyVarsGen.instance(context);
 168 
 169         Options options = Options.instance(context);
 170 
 171         Source source = Source.instance(context);
 172         allowReifiableTypesInInstanceof = Feature.REIFIABLE_TYPES_INSTANCEOF.allowedInSource(source);
 173         allowRecords = Feature.RECORDS.allowedInSource(source);
 174         allowPatternSwitch = (preview.isEnabled() || !preview.isPreview(Feature.PATTERN_SWITCH)) &&
 175                              Feature.PATTERN_SWITCH.allowedInSource(source);
 176         allowUnconditionalPatternsInstanceOf =
 177                              Feature.UNCONDITIONAL_PATTERN_IN_INSTANCEOF.allowedInSource(source);
 178         sourceName = source.name;
 179         useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning");
 180 
 181         statInfo = new ResultInfo(KindSelector.NIL, Type.noType);
 182         varAssignmentInfo = new ResultInfo(KindSelector.ASG, Type.noType);
 183         unknownExprInfo = new ResultInfo(KindSelector.VAL, Type.noType);
 184         methodAttrInfo = new MethodAttrInfo();
 185         unknownTypeInfo = new ResultInfo(KindSelector.TYP, Type.noType);
 186         unknownTypeExprInfo = new ResultInfo(KindSelector.VAL_TYP, Type.noType);
 187         recoveryInfo = new RecoveryInfo(deferredAttr.emptyDeferredAttrContext);
 188         initBlockType = new MethodType(List.nil(), syms.voidType, List.nil(), syms.methodClass);
 189         allowValueClasses = (!preview.isPreview(Feature.VALUE_CLASSES) || preview.isEnabled()) &&
 190                 Feature.VALUE_CLASSES.allowedInSource(source);
 191     }
 192 
 193     /** Switch: reifiable types in instanceof enabled?
 194      */
 195     boolean allowReifiableTypesInInstanceof;
 196 
 197     /** Are records allowed
 198      */
 199     private final boolean allowRecords;
 200 
 201     /** Are patterns in switch allowed
 202      */
 203     private final boolean allowPatternSwitch;
 204 
 205     /** Are unconditional patterns in instanceof allowed
 206      */
 207     private final boolean allowUnconditionalPatternsInstanceOf;
 208 
 209     /** Are value classes allowed
 210      */
 211     private final boolean allowValueClasses;
 212 
 213     /**
 214      * Switch: warn about use of variable before declaration?
 215      * RFE: 6425594
 216      */
 217     boolean useBeforeDeclarationWarning;
 218 
 219     /**
 220      * Switch: name of source level; used for error reporting.
 221      */
 222     String sourceName;
 223 
 224     /** Check kind and type of given tree against protokind and prototype.
 225      *  If check succeeds, store type in tree and return it.
 226      *  If check fails, store errType in tree and return it.
 227      *  No checks are performed if the prototype is a method type.
 228      *  It is not necessary in this case since we know that kind and type
 229      *  are correct.
 230      *
 231      *  @param tree     The tree whose kind and type is checked
 232      *  @param found    The computed type of the tree

 286               owner.kind == VAR ||           // i.e. we are in a variable initializer
 287               (owner.flags() & BLOCK) != 0)  // i.e. we are in an initializer block
 288              &&
 289              v.owner == owner.owner
 290              &&
 291              ((v.flags() & STATIC) != 0) == Resolve.isStatic(env));
 292         boolean insideCompactConstructor = env.enclMethod != null && TreeInfo.isCompactConstructor(env.enclMethod);
 293         return isAssignable & !insideCompactConstructor;
 294     }
 295 
 296     /** Check that variable can be assigned to.
 297      *  @param pos    The current source code position.
 298      *  @param v      The assigned variable
 299      *  @param base   If the variable is referred to in a Select, the part
 300      *                to the left of the `.', null otherwise.
 301      *  @param env    The current environment.
 302      */
 303     void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, Env<AttrContext> env) {
 304         if (v.name == names._this) {
 305             log.error(pos, Errors.CantAssignValToThis);
 306         } else if ((v.flags() & FINAL) != 0 &&


 307             ((v.flags() & HASINIT) != 0
 308              ||
 309              !((base == null ||
 310                TreeInfo.isThisQualifier(base)) &&
 311                isAssignableAsBlankFinal(v, env)))) {
 312             if (v.isResourceVariable()) { //TWR resource
 313                 log.error(pos, Errors.TryResourceMayNotBeAssigned(v));
 314             } else {
 315                 log.error(pos, Errors.CantAssignValToVar(Flags.toSource(v.flags() & (STATIC | FINAL)), v));
 316             }

















 317         }
 318     }
 319 
 320     /** Does tree represent a static reference to an identifier?
 321      *  It is assumed that tree is either a SELECT or an IDENT.
 322      *  We have to weed out selects from non-type names here.
 323      *  @param tree    The candidate tree.
 324      */
 325     boolean isStaticReference(JCTree tree) {
 326         if (tree.hasTag(SELECT)) {
 327             Symbol lsym = TreeInfo.symbol(((JCFieldAccess) tree).selected);
 328             if (lsym == null || lsym.kind != TYP) {
 329                 return false;
 330             }
 331         }
 332         return true;
 333     }
 334 
 335     /** Is this symbol a type?
 336      */

1094                          *     - have an accessibility stricter than that of the record type
1095                          *     - explicitly invoke any other constructor
1096                          */
1097                         if ((tree.sym.flags_field & GENERATEDCONSTR) == 0) {
1098                             if (Check.protection(m.flags()) > Check.protection(env.enclClass.sym.flags())) {
1099                                 log.error(tree,
1100                                         (env.enclClass.sym.flags() & AccessFlags) == 0 ?
1101                                             Errors.InvalidCanonicalConstructorInRecord(
1102                                                 Fragments.Canonical,
1103                                                 env.enclClass.sym.name,
1104                                                 Fragments.CanonicalMustNotHaveStrongerAccess("package")
1105                                             ) :
1106                                             Errors.InvalidCanonicalConstructorInRecord(
1107                                                     Fragments.Canonical,
1108                                                     env.enclClass.sym.name,
1109                                                     Fragments.CanonicalMustNotHaveStrongerAccess(asFlagSet(env.enclClass.sym.flags() & AccessFlags))
1110                                             )
1111                                 );
1112                             }
1113 
1114                             if (!allowValueClasses && TreeInfo.hasAnyConstructorCall(tree)) {
1115                                 log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1116                                         Fragments.Canonical, env.enclClass.sym.name,
1117                                         Fragments.CanonicalMustNotContainExplicitConstructorInvocation));
1118                             }
1119                         }
1120 
1121                         // also we want to check that no type variables have been defined
1122                         if (!tree.typarams.isEmpty()) {
1123                             log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1124                                     Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalMustNotDeclareTypeVariables));
1125                         }
1126 
1127                         /* and now we need to check that the constructor's arguments are exactly the same as those of the
1128                          * record components
1129                          */
1130                         List<? extends RecordComponent> recordComponents = env.enclClass.sym.getRecordComponents();
1131                         List<Type> recordFieldTypes = TreeInfo.recordFields(env.enclClass).map(vd -> vd.sym.type);
1132                         for (JCVariableDecl param: tree.params) {
1133                             boolean paramIsVarArgs = (param.sym.flags_field & VARARGS) != 0;
1134                             if (!types.isSameType(param.type, recordFieldTypes.head) ||

1176                 }
1177                 if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0)
1178                     log.error(tree.pos(), Errors.MissingMethBodyOrDeclAbstract);
1179             } else {
1180                 if ((tree.sym.flags() & (ABSTRACT|DEFAULT|PRIVATE)) == ABSTRACT) {
1181                     if ((owner.flags() & INTERFACE) != 0) {
1182                         log.error(tree.body.pos(), Errors.IntfMethCantHaveBody);
1183                     } else {
1184                         log.error(tree.pos(), Errors.AbstractMethCantHaveBody);
1185                     }
1186                 } else if ((tree.mods.flags & NATIVE) != 0) {
1187                     log.error(tree.pos(), Errors.NativeMethCantHaveBody);
1188                 }
1189                 // Add an implicit super() call unless an explicit call to
1190                 // super(...) or this(...) is given
1191                 // or we are compiling class java.lang.Object.
1192                 if (isConstructor && owner.type != syms.objectType) {
1193                     if (!TreeInfo.hasAnyConstructorCall(tree)) {
1194                         JCStatement supCall = make.at(tree.body.pos).Exec(make.Apply(List.nil(),
1195                                 make.Ident(names._super), make.Idents(List.nil())));
1196                         if (allowValueClasses && (owner.isValueClass() || owner.hasStrict() || ((owner.flags_field & RECORD) != 0))) {
1197                             tree.body.stats = tree.body.stats.append(supCall);
1198                         } else {
1199                             tree.body.stats = tree.body.stats.prepend(supCall);
1200                         }
1201                     } else if ((env.enclClass.sym.flags() & ENUM) != 0 &&
1202                             (tree.mods.flags & GENERATEDCONSTR) == 0 &&
1203                             TreeInfo.hasConstructorCall(tree, names._super)) {
1204                         // enum constructors are not allowed to call super
1205                         // directly, so make sure there aren't any super calls
1206                         // in enum constructors, except in the compiler
1207                         // generated one.
1208                         log.error(tree.body.stats.head.pos(),
1209                                   Errors.CallToSuperNotAllowedInEnumCtor(env.enclClass.sym));
1210                     }
1211                     if (env.enclClass.sym.isRecord() && (tree.sym.flags_field & RECORD) != 0) { // we are seeing the canonical constructor
1212                         List<Name> recordComponentNames = TreeInfo.recordFields(env.enclClass).map(vd -> vd.sym.name);
1213                         List<Name> initParamNames = tree.sym.params.map(p -> p.name);
1214                         if (!initParamNames.equals(recordComponentNames)) {
1215                             log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1216                                     Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalWithNameMismatch));
1217                         }
1218                         if (tree.sym.type.asMethodType().thrown != null && !tree.sym.type.asMethodType().thrown.isEmpty()) {
1219                             log.error(tree,
1220                                     Errors.InvalidCanonicalConstructorInRecord(
1221                                             TreeInfo.isCompactConstructor(tree) ? Fragments.Compact : Fragments.Canonical,
1222                                             env.enclClass.sym.name,
1223                                             Fragments.ThrowsClauseNotAllowedForCanonicalConstructor(
1224                                                     TreeInfo.isCompactConstructor(tree) ? Fragments.Compact : Fragments.Canonical)));
1225                         }
1226                     }
1227                 }
1228 
1229                 // Attribute all type annotations in the body
1230                 annotate.queueScanTreeAndTypeAnnotate(tree.body, localEnv, m, null);
1231                 annotate.flush();
1232 
1233                 // Start of constructor prologue
1234                 localEnv.info.ctorPrologue = isConstructor;
1235 
1236                 // Attribute method body.
1237                 attribStat(tree.body, localEnv);
1238                 if (isConstructor) {
1239                     ListBuffer<JCTree> prologueCode = new ListBuffer<>();
1240                     for (JCTree stat : tree.body.stats) {
1241                         prologueCode.add(stat);
1242                         /* gather all the stats in the body until a `super` or `this` constructor invocation is found,
1243                          * including the constructor invocation, that way we don't need to worry in the visitor below if
1244                          * if we are dealing or not with prologue code
1245                          */
1246                         if (stat instanceof JCExpressionStatement expStmt &&
1247                                 expStmt.expr instanceof JCMethodInvocation mi &&
1248                                 TreeInfo.isConstructorCall(mi)) {
1249                             break;
1250                         }
1251                     }
1252                     if (!prologueCode.isEmpty()) {
1253                         CtorPrologueVisitor ctorPrologueVisitor = new CtorPrologueVisitor(localEnv);
1254                         ctorPrologueVisitor.scan(prologueCode.toList());
1255                     }
1256                 }
1257             }
1258 
1259             localEnv.info.scope.leave();
1260             result = tree.type = m.type;
1261         } finally {
1262             chk.setLint(prevLint);
1263             chk.setMethod(prevMethod);
1264             env.info.ctorPrologue = ctorProloguePrev;
1265         }
1266     }
1267 
1268     class CtorPrologueVisitor extends TreeScanner {
1269         Env<AttrContext> localEnv;
1270         CtorPrologueVisitor(Env<AttrContext> localEnv) {
1271             this.localEnv = localEnv;
1272             currentClassSym = localEnv.enclClass.sym;
1273         }
1274 
1275         boolean insideLambdaOrClassDef = false;
1276 
1277         @Override
1278         public void visitLambda(JCLambda lambda) {
1279             boolean previousInsideLambdaOrClassDef = insideLambdaOrClassDef;
1280             try {
1281                 insideLambdaOrClassDef = true;
1282                 super.visitLambda(lambda);
1283             } finally {
1284                 insideLambdaOrClassDef = previousInsideLambdaOrClassDef;
1285             }
1286         }
1287 
1288         ClassSymbol currentClassSym;
1289 
1290         @Override
1291         public void visitClassDef(JCClassDecl classDecl) {
1292             boolean previousInsideLambdaOrClassDef = insideLambdaOrClassDef;
1293             ClassSymbol previousClassSym = currentClassSym;
1294             try {
1295                 insideLambdaOrClassDef = true;
1296                 currentClassSym = classDecl.sym;
1297                 super.visitClassDef(classDecl);
1298             } finally {
1299                 insideLambdaOrClassDef = previousInsideLambdaOrClassDef;
1300                 currentClassSym = previousClassSym;
1301             }
1302         }
1303 
1304         private void reportPrologueError(JCTree tree, Symbol sym) {
1305             preview.checkSourceLevel(tree, Feature.FLEXIBLE_CONSTRUCTORS);
1306             log.error(tree, Errors.CantRefBeforeCtorCalled(sym));
1307         }
1308 
1309         @Override
1310         public void visitApply(JCMethodInvocation tree) {
1311             super.visitApply(tree);
1312             Name name = TreeInfo.name(tree.meth);
1313             boolean isConstructorCall = name == names._this || name == names._super;
1314             Symbol msym = TreeInfo.symbolFor(tree.meth);
1315             // is this an instance method call or an illegal constructor invocation like: `this.super()`?
1316             if (msym != null && // for erroneous invocations msym can be null, ignore those
1317                 (!isConstructorCall ||
1318                 isConstructorCall && tree.meth.hasTag(SELECT))) {
1319                 if (isEarlyReference(localEnv, tree.meth, msym))
1320                     reportPrologueError(tree.meth, msym);
1321             }
1322         }
1323 
1324         @Override
1325         public void visitIdent(JCIdent tree) {
1326             analyzeSymbol(tree);
1327         }
1328 
1329         @Override
1330         public void visitSelect(JCFieldAccess tree) {
1331             SelectScanner ss = new SelectScanner();
1332             ss.scan(tree);
1333             if (ss.scanLater == null) {
1334                 analyzeSymbol(tree);
1335             } else {
1336                 boolean prevLhs = isInLHS;
1337                 try {
1338                     isInLHS = false;
1339                     scan(ss.scanLater);
1340                 } finally {
1341                     isInLHS = prevLhs;
1342                 }
1343             }
1344         }
1345 
1346         @Override
1347         public void visitNewClass(JCNewClass tree) {
1348             super.visitNewClass(tree);
1349             checkNewClassAndMethRefs(tree, tree.type);
1350         }
1351 
1352         @Override
1353         public void visitReference(JCMemberReference tree) {
1354             super.visitReference(tree);
1355             if (tree.getMode() == JCMemberReference.ReferenceMode.NEW) {
1356                 checkNewClassAndMethRefs(tree, tree.expr.type);
1357             }
1358         }
1359 
1360         void checkNewClassAndMethRefs(JCTree tree, Type t) {
1361             if (t.tsym.isEnclosedBy(localEnv.enclClass.sym) &&
1362                     !t.tsym.isStatic() &&
1363                     !t.tsym.isDirectlyOrIndirectlyLocal()) {
1364                 reportPrologueError(tree, t.getEnclosingType().tsym);
1365             }
1366         }
1367 
1368         /* if a symbol is in the LHS of an assignment expression we won't consider it as a candidate
1369          * for a proxy local variable later on
1370          */
1371         boolean isInLHS = false;
1372 
1373         @Override
1374         public void visitAssign(JCAssign tree) {
1375             boolean previousIsInLHS = isInLHS;
1376             try {
1377                 isInLHS = true;
1378                 scan(tree.lhs);
1379             } finally {
1380                 isInLHS = previousIsInLHS;
1381             }
1382             scan(tree.rhs);
1383         }
1384 
1385         @Override
1386         public void visitMethodDef(JCMethodDecl tree) {
1387             // ignore any declarative part, mainly to avoid scanning receiver parameters
1388             scan(tree.body);
1389         }
1390 
1391         void analyzeSymbol(JCTree tree) {
1392             Symbol sym = TreeInfo.symbolFor(tree);
1393             // make sure that there is a symbol and it is not static
1394             if (sym == null || sym.isStatic()) {
1395                 return;
1396             }
1397             if (isInLHS && !insideLambdaOrClassDef) {
1398                 // Check instance field assignments that appear in constructor prologues
1399                 if (isEarlyReference(localEnv, tree, sym)) {
1400                     // Field may not be inherited from a superclass
1401                     if (sym.owner != localEnv.enclClass.sym) {
1402                         log.error(tree, Errors.CantRefBeforeCtorCalled(sym));
1403                         return;
1404                     }
1405                     // Field may not have an initializer
1406                     if ((sym.flags() & HASINIT) != 0) {
1407                         log.error(tree, Errors.CantAssignInitializedBeforeCtorCalled(sym));
1408                         return;
1409                     }
1410                 }
1411                 return;
1412             }
1413             tree = TreeInfo.skipParens(tree);
1414             if (sym.kind == VAR && sym.owner.kind == TYP) {
1415                 if (sym.name == names._this || sym.name == names._super) {
1416                     // are we seeing something like `this` or `CurrentClass.this` or `SuperClass.super::foo`?
1417                     if (TreeInfo.isExplicitThisReference(
1418                             types,
1419                             (ClassType)localEnv.enclClass.sym.type,
1420                             tree)) {
1421                         reportPrologueError(tree, sym);
1422                     }
1423                 } else if (sym.kind == VAR && sym.owner.kind == TYP) { // now fields only
1424                     if (sym.owner != localEnv.enclClass.sym) {
1425                         if (localEnv.enclClass.sym.isSubClass(sym.owner, types) &&
1426                                 sym.isInheritedIn(localEnv.enclClass.sym, types)) {
1427                             /* if we are dealing with a field that doesn't belong to the current class, but the
1428                              * field is inherited, this is an error. Unless, the super class is also an outer
1429                              * class and the field's qualifier refers to the outer class
1430                              */
1431                             if (tree.hasTag(IDENT) ||
1432                                 TreeInfo.isExplicitThisReference(
1433                                         types,
1434                                         (ClassType)localEnv.enclClass.sym.type,
1435                                         ((JCFieldAccess)tree).selected)) {
1436                                 reportPrologueError(tree, sym);
1437                             }
1438                         }
1439                     } else if (isEarlyReference(localEnv, tree, sym)) {
1440                         /* now this is a `proper` instance field of the current class
1441                          * references to fields of identity classes which happen to have initializers are
1442                          * not allowed in the prologue
1443                          */
1444                         if (insideLambdaOrClassDef ||
1445                             (!localEnv.enclClass.sym.isValueClass() && (sym.flags_field & HASINIT) != 0))
1446                             reportPrologueError(tree, sym);
1447                         // we will need to generate a proxy for this field later on
1448                         if (!isInLHS) {
1449                             if (allowValueClasses) {
1450                                 localProxyVarsGen.addFieldReadInPrologue(localEnv.enclMethod, sym);
1451                             } else {
1452                                 reportPrologueError(tree, sym);
1453                             }
1454                         }
1455                     }
1456                 }
1457             }
1458         }
1459 
1460         /**
1461          * Determine if the symbol appearance constitutes an early reference to the current class.
1462          *
1463          * <p>
1464          * This means the symbol is an instance field, or method, of the current class and it appears
1465          * in an early initialization context of it (i.e., one of its constructor prologues).
1466          *
1467          * @param env    The current environment
1468          * @param tree   the AST referencing the variable
1469          * @param sym    The symbol
1470          */
1471         private boolean isEarlyReference(Env<AttrContext> env, JCTree tree, Symbol sym) {
1472             if ((sym.flags() & STATIC) == 0 &&
1473                     (sym.kind == VAR || sym.kind == MTH) &&
1474                     sym.isMemberOf(env.enclClass.sym, types)) {
1475                 // Allow "Foo.this.x" when "Foo" is (also) an outer class, as this refers to the outer instance
1476                 if (tree instanceof JCFieldAccess fa) {
1477                     return TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, fa.selected);
1478                 } else if (currentClassSym != env.enclClass.sym) {
1479                     /* so we are inside a class, CI, in the prologue of an outer class, CO, and the symbol being
1480                      * analyzed has no qualifier. So if the symbol is a member of CI the reference is allowed,
1481                      * otherwise it is not.
1482                      * It could be that the reference to CI's member happens inside CI's own prologue, but that
1483                      * will be checked separately, when CI's prologue is analyzed.
1484                      */
1485                     return !sym.isMemberOf(currentClassSym, types);
1486                 }
1487                 return true;
1488             }
1489             return false;
1490         }
1491 
1492         /* scanner for a select expression, anything that is not a select or identifier
1493          * will be stored for further analysis
1494          */
1495         class SelectScanner extends DeferredAttr.FilterScanner {
1496             JCTree scanLater;
1497 
1498             SelectScanner() {
1499                 super(Set.of(IDENT, SELECT, PARENS));
1500             }
1501 
1502             @Override
1503             void skip(JCTree tree) {
1504                 scanLater = tree;
1505             }
1506         }
1507     }
1508 
1509     public void visitVarDef(JCVariableDecl tree) {
1510         // Local variables have not been entered yet, so we need to do it now:
1511         if (env.info.scope.owner.kind == MTH || env.info.scope.owner.kind == VAR) {
1512             if (tree.sym != null) {
1513                 // parameters have already been entered
1514                 env.info.scope.enter(tree.sym);
1515             } else {
1516                 if (tree.isImplicitlyTyped() && (tree.getModifiers().flags & PARAMETER) == 0) {
1517                     if (tree.init == null) {
1518                         //cannot use 'var' without initializer
1519                         log.error(tree, Errors.CantInferLocalVarType(tree.name, Fragments.LocalMissingInit));
1520                         tree.vartype = make.Erroneous();
1521                     } else {
1522                         Fragment msg = canInferLocalVarType(tree);
1523                         if (msg != null) {
1524                             //cannot use 'var' with initializer which require an explicit target
1525                             //(e.g. lambda, method reference, array initializer).
1526                             log.error(tree, Errors.CantInferLocalVarType(tree.name, msg));
1527                             tree.vartype = make.Erroneous();
1528                         }

1550         chk.validate(tree.vartype, env, !isImplicitLambdaParameter && !tree.isImplicitlyTyped());
1551 
1552         try {
1553             v.getConstValue(); // ensure compile-time constant initializer is evaluated
1554             deferredLintHandler.flush(tree, lint);
1555             chk.checkDeprecatedAnnotation(tree.pos(), v);
1556 
1557             if (tree.init != null) {
1558                 if ((v.flags_field & FINAL) == 0 ||
1559                     !memberEnter.needsLazyConstValue(tree.init)) {
1560                     // Not a compile-time constant
1561                     // Attribute initializer in a new environment
1562                     // with the declared variable as owner.
1563                     // Check that initializer conforms to variable's declared type.
1564                     Env<AttrContext> initEnv = memberEnter.initEnv(tree, env);
1565                     initEnv.info.lint = lint;
1566                     // In order to catch self-references, we set the variable's
1567                     // declaration position to maximal possible value, effectively
1568                     // marking the variable as undefined.
1569                     initEnv.info.enclVar = v;
1570                     boolean previousCtorPrologue = initEnv.info.ctorPrologue;
1571                     try {
1572                         if (v.owner.kind == TYP && !v.isStatic() && v.isStrict()) {
1573                             // strict instance initializer in a value class
1574                             initEnv.info.ctorPrologue = true;
1575                         }
1576                         attribExpr(tree.init, initEnv, v.type);
1577                         if (tree.isImplicitlyTyped()) {
1578                             //fixup local variable type
1579                             v.type = chk.checkLocalVarType(tree, tree.init.type, tree.name);
1580                         }
1581                         if (v.owner.kind == TYP && !v.isStatic() && v.isStrict()) {
1582                             // strict field initializers are inlined in constructor's prologues
1583                             CtorPrologueVisitor ctorPrologueVisitor = new CtorPrologueVisitor(initEnv);
1584                             ctorPrologueVisitor.scan(tree.init);
1585                         }
1586                     } finally {
1587                         initEnv.info.ctorPrologue = previousCtorPrologue;
1588                     }
1589                 }
1590                 if (tree.isImplicitlyTyped()) {
1591                     setSyntheticVariableType(tree, v.type);
1592                 }
1593             }
1594             result = tree.type = v.type;
1595             if (env.enclClass.sym.isRecord() && tree.sym.owner.kind == TYP && !v.isStatic()) {
1596                 if (isNonArgsMethodInObject(v.name)) {
1597                     log.error(tree, Errors.IllegalRecordComponentName(v));
1598                 }
1599             }
1600             chk.checkRequiresIdentity(tree, env.info.lint);
1601         }
1602         finally {
1603             chk.setLint(prevLint);
1604         }
1605     }
1606 
1607     private void doQueueScanTreeAndTypeAnnotateForVarInit(JCVariableDecl tree, Env<AttrContext> env) {

1688             }
1689         }
1690     }
1691 
1692     public void visitSkip(JCSkip tree) {
1693         result = null;
1694     }
1695 
1696     public void visitBlock(JCBlock tree) {
1697         if (env.info.scope.owner.kind == TYP || env.info.scope.owner.kind == ERR) {
1698             // Block is a static or instance initializer;
1699             // let the owner of the environment be a freshly
1700             // created BLOCK-method.
1701             Symbol fakeOwner =
1702                 new MethodSymbol(tree.flags | BLOCK |
1703                     env.info.scope.owner.flags() & STRICTFP, names.empty, initBlockType,
1704                     env.info.scope.owner);
1705             final Env<AttrContext> localEnv =
1706                 env.dup(tree, env.info.dup(env.info.scope.dupUnshared(fakeOwner)));
1707 
1708             if ((tree.flags & STATIC) != 0) {
1709                 localEnv.info.staticLevel++;
1710             } else {
1711                 localEnv.info.instanceInitializerBlock = true;
1712             }
1713             // Attribute all type annotations in the block
1714             annotate.queueScanTreeAndTypeAnnotate(tree, localEnv, localEnv.info.scope.owner, null);
1715             annotate.flush();
1716             attribStats(tree.stats, localEnv);
1717 
1718             {
1719                 // Store init and clinit type annotations with the ClassSymbol
1720                 // to allow output in Gen.normalizeDefs.
1721                 ClassSymbol cs = (ClassSymbol)env.info.scope.owner;
1722                 List<Attribute.TypeCompound> tas = localEnv.info.scope.owner.getRawTypeAttributes();
1723                 if ((tree.flags & STATIC) != 0) {
1724                     cs.appendClassInitTypeAttributes(tas);
1725                 } else {
1726                     cs.appendInitTypeAttributes(tas);
1727                 }
1728             }
1729         } else {
1730             // Create a new local environment with a local scope.
1731             Env<AttrContext> localEnv =
1732                 env.dup(tree, env.info.dup(env.info.scope.dup()));

2205     // where
2206     /** Return the selected enumeration constant symbol, or null. */
2207     private Symbol enumConstant(JCTree tree, Type enumType) {
2208         if (tree.hasTag(IDENT)) {
2209             JCIdent ident = (JCIdent)tree;
2210             Name name = ident.name;
2211             for (Symbol sym : enumType.tsym.members().getSymbolsByName(name)) {
2212                 if (sym.kind == VAR) {
2213                     Symbol s = ident.sym = sym;
2214                     ((VarSymbol)s).getConstValue(); // ensure initializer is evaluated
2215                     ident.type = s.type;
2216                     return ((s.flags_field & Flags.ENUM) == 0)
2217                         ? null : s;
2218                 }
2219             }
2220         }
2221         return null;
2222     }
2223 
2224     public void visitSynchronized(JCSynchronized tree) {
2225         boolean identityType = chk.checkIdentityType(tree.pos(), attribExpr(tree.lock, env));
2226         if (identityType && tree.lock.type != null && tree.lock.type.isValueBased()) {
2227             env.info.lint.logIfEnabled(tree.pos(), LintWarnings.AttemptToSynchronizeOnInstanceOfValueBasedClass);
2228         }
2229         attribStat(tree.body, env);
2230         result = null;
2231     }
2232 
2233     public void visitTry(JCTry tree) {
2234         // Create a new local environment with a local
2235         Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
2236         try {
2237             boolean isTryWithResource = tree.resources.nonEmpty();
2238             // Create a nested environment for attributing the try block if needed
2239             Env<AttrContext> tryEnv = isTryWithResource ?
2240                 env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) :
2241                 localEnv;
2242             try {
2243                 // Attribute resource declarations
2244                 for (JCTree resource : tree.resources) {
2245                     CheckContext twrContext = new Check.NestedCheckContext(resultInfo.checkContext) {
2246                         @Override

4660     }
4661 
4662     public void visitSelect(JCFieldAccess tree) {
4663         // Determine the expected kind of the qualifier expression.
4664         KindSelector skind = KindSelector.NIL;
4665         if (tree.name == names._this || tree.name == names._super ||
4666                 tree.name == names._class)
4667         {
4668             skind = KindSelector.TYP;
4669         } else {
4670             if (pkind().contains(KindSelector.PCK))
4671                 skind = KindSelector.of(skind, KindSelector.PCK);
4672             if (pkind().contains(KindSelector.TYP))
4673                 skind = KindSelector.of(skind, KindSelector.TYP, KindSelector.PCK);
4674             if (pkind().contains(KindSelector.VAL_MTH))
4675                 skind = KindSelector.of(skind, KindSelector.VAL, KindSelector.TYP);
4676         }
4677 
4678         // Attribute the qualifier expression, and determine its symbol (if any).
4679         Type site = attribTree(tree.selected, env, new ResultInfo(skind, Type.noType));
4680         Assert.check(site == tree.selected.type);
4681         if (!pkind().contains(KindSelector.TYP_PCK))
4682             site = capture(site); // Capture field access
4683 
4684         // don't allow T.class T[].class, etc
4685         if (skind == KindSelector.TYP) {
4686             Type elt = site;
4687             while (elt.hasTag(ARRAY))
4688                 elt = ((ArrayType)elt).elemtype;
4689             if (elt.hasTag(TYPEVAR)) {
4690                 log.error(tree.pos(), Errors.TypeVarCantBeDeref);
4691                 result = tree.type = types.createErrorType(tree.name, site.tsym, site);
4692                 tree.sym = tree.type.tsym;
4693                 return ;
4694             }
4695         }
4696 
4697         // If qualifier symbol is a type or `super', assert `selectSuper'
4698         // for the selection. This is relevant for determining whether
4699         // protected symbols are accessible.
4700         Symbol sitesym = TreeInfo.symbol(tree.selected);

5764                                                       .filter(s -> s.tsym.isSealed())
5765                                                       .map(s -> (ClassSymbol) s.tsym)
5766                                                       .collect(List.collector());
5767 
5768                 if (sealedSupers.isEmpty()) {
5769                     if ((c.flags_field & Flags.NON_SEALED) != 0) {
5770                         boolean hasErrorSuper = false;
5771 
5772                         hasErrorSuper |= types.directSupertypes(c.type)
5773                                               .stream()
5774                                               .anyMatch(s -> s.tsym.kind == Kind.ERR);
5775 
5776                         ClassType ct = (ClassType) c.type;
5777 
5778                         hasErrorSuper |= !ct.isCompound() && ct.interfaces_field != ct.all_interfaces_field;
5779 
5780                         if (!hasErrorSuper) {
5781                             log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.NonSealedWithNoSealedSupertype(c));
5782                         }
5783                     }
5784                 } else if ((c.flags_field & Flags.COMPOUND) == 0) {
5785                     if (c.isDirectlyOrIndirectlyLocal() && !c.isEnum()) {
5786                         log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.LocalClassesCantExtendSealed(c.isAnonymous() ? Fragments.Anonymous : Fragments.Local));
5787                     }
5788 
5789                     if (!c.type.isCompound()) {
5790                         for (ClassSymbol supertypeSym : sealedSupers) {
5791                             if (!supertypeSym.isPermittedSubclass(c.type.tsym)) {
5792                                 log.error(TreeInfo.diagnosticPositionFor(c.type.tsym, env.tree), Errors.CantInheritFromSealed(supertypeSym));
5793                             }
5794                         }
5795                         if (!c.isNonSealed() && !c.isFinal() && !c.isSealed()) {
5796                             log.error(TreeInfo.diagnosticPositionFor(c, env.tree),
5797                                     c.isInterface() ?
5798                                             Errors.NonSealedOrSealedExpected :
5799                                             Errors.NonSealedSealedOrFinalExpected);
5800                         }
5801                     }
5802                 }
5803 
5804                 deferredLintHandler.flush(env.tree, env.info.lint);
5805                 env.info.returnResult = null;
5806                 // java.lang.Enum may not be subclassed by a non-enum
5807                 if (st.tsym == syms.enumSym &&
5808                     ((c.flags_field & (Flags.ENUM|Flags.COMPOUND)) == 0))
5809                     log.error(env.tree.pos(), Errors.EnumNoSubclassing);
5810 
5811                 // Enums may not be extended by source-level classes
5812                 if (st.tsym != null &&
5813                     ((st.tsym.flags_field & Flags.ENUM) != 0) &&
5814                     ((c.flags_field & (Flags.ENUM | Flags.COMPOUND)) == 0)) {
5815                     log.error(env.tree.pos(), Errors.EnumTypesNotExtensible);
5816                 }
5817 
5818                 if (rs.isSerializable(c.type)) {
5819                     env.info.isSerializable = true;
5820                 }
5821 
5822                 if (c.isValueClass()) {
5823                     Assert.check(env.tree.hasTag(CLASSDEF));
5824                     chk.checkConstraintsOfValueClass((JCClassDecl) env.tree, c);
5825                 }
5826 
5827                 attribClassBody(env, c);
5828 
5829                 chk.checkDeprecatedAnnotation(env.tree.pos(), c);
5830                 chk.checkClassOverrideEqualsAndHashIfNeeded(env.tree.pos(), c);
5831                 chk.checkFunctionalInterface((JCClassDecl) env.tree, c);
5832                 chk.checkLeaksNotAccessible(env, (JCClassDecl) env.tree);
5833 
5834                 if (c.isImplicit()) {
5835                     chk.checkHasMain(env.tree.pos(), c);
5836                 }
5837             } finally {
5838                 env.info.returnResult = prevReturnRes;
5839                 log.useSource(prev);
5840                 chk.setLint(prevLint);
5841             }
5842 
5843         }
5844     }
5845 
5846     public void visitImport(JCImport tree) {

5951                         sym.kind != VAR ||
5952                         sym.getConstValue() == null)
5953                     log.error(l.head.pos(), Errors.IclsCantHaveStaticDecl(c));
5954             }
5955         }
5956 
5957         // Check for proper placement of super()/this() calls.
5958         chk.checkSuperInitCalls(tree);
5959 
5960         // Check for cycles among non-initial constructors.
5961         chk.checkCyclicConstructors(tree);
5962 
5963         // Check for cycles among annotation elements.
5964         chk.checkNonCyclicElements(tree);
5965 
5966         // Check for proper use of serialVersionUID and other
5967         // serialization-related fields and methods
5968         if (env.info.lint.isEnabled(LintCategory.SERIAL)
5969                 && rs.isSerializable(c.type)
5970                 && !c.isAnonymous()) {
5971             chk.checkSerialStructure(env, tree, c);
5972         }
5973         // Correctly organize the positions of the type annotations
5974         typeAnnotations.organizeTypeAnnotationsBodies(tree);
5975 
5976         // Check type annotations applicability rules
5977         validateTypeAnnotations(tree, false);
5978     }
5979         // where
5980         /** get a diagnostic position for an attribute of Type t, or null if attribute missing */
5981         private DiagnosticPosition getDiagnosticPosition(JCClassDecl tree, Type t) {
5982             for(List<JCAnnotation> al = tree.mods.annotations; !al.isEmpty(); al = al.tail) {
5983                 if (types.isSameType(al.head.annotationType.type, t))
5984                     return al.head.pos();
5985             }
5986 
5987             return null;
5988         }
5989 
5990     private Type capture(Type type) {
5991         return types.capture(type);
< prev index next >