< prev index next >

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

Print this page

   1 /*
   2  * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any

 107     final Analyzer analyzer;
 108     final DeferredAttr deferredAttr;
 109     final Check chk;
 110     final Flow flow;
 111     final MemberEnter memberEnter;
 112     final TypeEnter typeEnter;
 113     final TreeMaker make;
 114     final ConstFold cfolder;
 115     final Enter enter;
 116     final Target target;
 117     final Types types;
 118     final Preview preview;
 119     final JCDiagnostic.Factory diags;
 120     final TypeAnnotations typeAnnotations;
 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 boolean captureMRefReturnType;
 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         lintMapper = LintMapper.instance(context);
 143         syms = Symtab.instance(context);
 144         rs = Resolve.instance(context);
 145         operators = Operators.instance(context);
 146         chk = Check.instance(context);
 147         flow = Flow.instance(context);
 148         memberEnter = MemberEnter.instance(context);
 149         typeEnter = TypeEnter.instance(context);
 150         make = TreeMaker.instance(context);
 151         enter = Enter.instance(context);
 152         infer = Infer.instance(context);
 153         analyzer = Analyzer.instance(context);
 154         deferredAttr = DeferredAttr.instance(context);
 155         cfolder = ConstFold.instance(context);
 156         target = Target.instance(context);
 157         types = Types.instance(context);
 158         preview = Preview.instance(context);
 159         diags = JCDiagnostic.Factory.instance(context);
 160         annotate = Annotate.instance(context);
 161         typeAnnotations = TypeAnnotations.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 
 168         Options options = Options.instance(context);
 169 
 170         Source source = Source.instance(context);
 171         allowReifiableTypesInInstanceof = Feature.REIFIABLE_TYPES_INSTANCEOF.allowedInSource(source);
 172         allowRecords = Feature.RECORDS.allowedInSource(source);
 173         allowPatternSwitch = (preview.isEnabled() || !preview.isPreview(Feature.PATTERN_SWITCH)) &&
 174                              Feature.PATTERN_SWITCH.allowedInSource(source);
 175         allowUnconditionalPatternsInstanceOf =
 176                              Feature.UNCONDITIONAL_PATTERN_IN_INSTANCEOF.allowedInSource(source);
 177         sourceName = source.name;
 178         useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning");
 179         captureMRefReturnType = Source.Feature.CAPTURE_MREF_RETURN_TYPE.allowedInSource(source);
 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     }
 190 
 191     /** Switch: reifiable types in instanceof enabled?
 192      */
 193     boolean allowReifiableTypesInInstanceof;
 194 
 195     /** Are records allowed
 196      */
 197     private final boolean allowRecords;
 198 
 199     /** Are patterns in switch allowed
 200      */
 201     private final boolean allowPatternSwitch;
 202 
 203     /** Are unconditional patterns in instanceof allowed
 204      */
 205     private final boolean allowUnconditionalPatternsInstanceOf;
 206 




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

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

1104                          *     - have an accessibility stricter than that of the record type
1105                          *     - explicitly invoke any other constructor
1106                          */
1107                         if ((tree.sym.flags_field & GENERATEDCONSTR) == 0) {
1108                             if (Check.protection(m.flags()) > Check.protection(env.enclClass.sym.flags())) {
1109                                 log.error(tree,
1110                                         (env.enclClass.sym.flags() & AccessFlags) == 0 ?
1111                                             Errors.InvalidCanonicalConstructorInRecord(
1112                                                 Fragments.Canonical,
1113                                                 env.enclClass.sym.name,
1114                                                 Fragments.CanonicalMustNotHaveStrongerAccess("package")
1115                                             ) :
1116                                             Errors.InvalidCanonicalConstructorInRecord(
1117                                                     Fragments.Canonical,
1118                                                     env.enclClass.sym.name,
1119                                                     Fragments.CanonicalMustNotHaveStrongerAccess(asFlagSet(env.enclClass.sym.flags() & AccessFlags))
1120                                             )
1121                                 );
1122                             }
1123 
1124                             if (TreeInfo.hasAnyConstructorCall(tree)) {

1125                                 log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1126                                         Fragments.Canonical, env.enclClass.sym.name,
1127                                         Fragments.CanonicalMustNotContainExplicitConstructorInvocation));
1128                             }
1129                         }
1130 
1131                         // also we want to check that no type variables have been defined
1132                         if (!tree.typarams.isEmpty()) {
1133                             log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1134                                     Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalMustNotDeclareTypeVariables));
1135                         }
1136 
1137                         /* and now we need to check that the constructor's arguments are exactly the same as those of the
1138                          * record components
1139                          */
1140                         List<? extends RecordComponent> recordComponents = env.enclClass.sym.getRecordComponents();
1141                         List<Type> recordFieldTypes = TreeInfo.recordFields(env.enclClass).map(vd -> vd.sym.type);
1142                         for (JCVariableDecl param: tree.params) {
1143                             boolean paramIsVarArgs = (param.sym.flags_field & VARARGS) != 0;
1144                             if (!types.isSameType(param.type, recordFieldTypes.head) ||

1182                 if (tree.defaultValue != null) {
1183                     if ((owner.flags() & ANNOTATION) == 0)
1184                         log.error(tree.pos(),
1185                                   Errors.DefaultAllowedInIntfAnnotationMember);
1186                 }
1187                 if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0)
1188                     log.error(tree.pos(), Errors.MissingMethBodyOrDeclAbstract(tree.sym, owner));
1189             } else {
1190                 if ((tree.sym.flags() & (ABSTRACT|DEFAULT|PRIVATE)) == ABSTRACT) {
1191                     if ((owner.flags() & INTERFACE) != 0) {
1192                         log.error(tree.body.pos(), Errors.IntfMethCantHaveBody);
1193                     } else {
1194                         log.error(tree.pos(), Errors.AbstractMethCantHaveBody);
1195                     }
1196                 } else if ((tree.mods.flags & NATIVE) != 0) {
1197                     log.error(tree.pos(), Errors.NativeMethCantHaveBody);
1198                 }
1199                 // Add an implicit super() call unless an explicit call to
1200                 // super(...) or this(...) is given
1201                 // or we are compiling class java.lang.Object.

1202                 if (isConstructor && owner.type != syms.objectType) {
1203                     if (!TreeInfo.hasAnyConstructorCall(tree)) {
1204                         JCStatement supCall = make.at(tree.body.pos).Exec(make.Apply(List.nil(),
1205                                 make.Ident(names._super), make.Idents(List.nil())));
1206                         tree.body.stats = tree.body.stats.prepend(supCall);





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





























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



























































































































































































































































































































































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

1283             }
1284         } else {
1285             doQueueScanTreeAndTypeAnnotateForVarInit(tree, env);
1286         }
1287 
1288         VarSymbol v = tree.sym;
1289         Lint lint = env.info.lint.augment(v);
1290         Lint prevLint = chk.setLint(lint);
1291 
1292         // Check that the variable's declared type is well-formed.
1293         boolean isImplicitLambdaParameter = env.tree.hasTag(LAMBDA) &&
1294                 ((JCLambda)env.tree).paramKind == JCLambda.ParameterKind.IMPLICIT &&
1295                 (tree.sym.flags() & PARAMETER) != 0;
1296         chk.validate(tree.vartype, env, !isImplicitLambdaParameter && !tree.isImplicitlyTyped());
1297 
1298         try {
1299             v.getConstValue(); // ensure compile-time constant initializer is evaluated
1300             chk.checkDeprecatedAnnotation(tree.pos(), v);
1301 
1302             if (tree.init != null) {

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









1319                     }
1320                 }







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

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




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

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

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





5557                 attribClassBody(env, c);
5558 
5559                 chk.checkDeprecatedAnnotation(env.tree.pos(), c);
5560                 chk.checkClassOverrideEqualsAndHashIfNeeded(env.tree.pos(), c);
5561                 chk.checkFunctionalInterface((JCClassDecl) env.tree, c);
5562                 chk.checkLeaksNotAccessible(env, (JCClassDecl) env.tree);
5563 
5564                 if (c.isImplicit()) {
5565                     chk.checkHasMain(env.tree.pos(), c);
5566                 }
5567             } finally {
5568                 env.info.returnResult = prevReturnRes;
5569                 log.useSource(prev);
5570                 chk.setLint(prevLint);
5571             }
5572 
5573         }
5574     }
5575 
5576     public void visitImport(JCImport tree) {

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

   1 /*
   2  * Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any

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

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


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

















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

1093                          *     - have an accessibility stricter than that of the record type
1094                          *     - explicitly invoke any other constructor
1095                          */
1096                         if ((tree.sym.flags_field & GENERATEDCONSTR) == 0) {
1097                             if (Check.protection(m.flags()) > Check.protection(env.enclClass.sym.flags())) {
1098                                 log.error(tree,
1099                                         (env.enclClass.sym.flags() & AccessFlags) == 0 ?
1100                                             Errors.InvalidCanonicalConstructorInRecord(
1101                                                 Fragments.Canonical,
1102                                                 env.enclClass.sym.name,
1103                                                 Fragments.CanonicalMustNotHaveStrongerAccess("package")
1104                                             ) :
1105                                             Errors.InvalidCanonicalConstructorInRecord(
1106                                                     Fragments.Canonical,
1107                                                     env.enclClass.sym.name,
1108                                                     Fragments.CanonicalMustNotHaveStrongerAccess(asFlagSet(env.enclClass.sym.flags() & AccessFlags))
1109                                             )
1110                                 );
1111                             }
1112 
1113                             if ((!allowValueClasses || TreeInfo.isCompactConstructor(tree)) &&
1114                                     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) ||

1172                 if (tree.defaultValue != null) {
1173                     if ((owner.flags() & ANNOTATION) == 0)
1174                         log.error(tree.pos(),
1175                                   Errors.DefaultAllowedInIntfAnnotationMember);
1176                 }
1177                 if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0)
1178                     log.error(tree.pos(), Errors.MissingMethBodyOrDeclAbstract(tree.sym, owner));
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                 boolean addedSuperInIdentityClass = false;
1193                 if (isConstructor && owner.type != syms.objectType) {
1194                     if (!TreeInfo.hasAnyConstructorCall(tree)) {
1195                         JCStatement supCall = make.at(tree.body.pos).Exec(make.Apply(List.nil(),
1196                                 make.Ident(names._super), make.Idents(List.nil())));
1197                         if (allowValueClasses && (owner.isValueClass() || ((owner.flags_field & RECORD) != 0))) {
1198                             tree.body.stats = tree.body.stats.append(supCall);
1199                         } else {
1200                             tree.body.stats = tree.body.stats.prepend(supCall);
1201                             addedSuperInIdentityClass = true;
1202                         }
1203                     } else if ((env.enclClass.sym.flags() & ENUM) != 0 &&
1204                             (tree.mods.flags & GENERATEDCONSTR) == 0 &&
1205                             TreeInfo.hasConstructorCall(tree, names._super)) {
1206                         // enum constructors are not allowed to call super
1207                         // directly, so make sure there aren't any super calls
1208                         // in enum constructors, except in the compiler
1209                         // generated one.
1210                         log.error(tree.body.stats.head.pos(),
1211                                   Errors.CallToSuperNotAllowedInEnumCtor(env.enclClass.sym));
1212                     }
1213                     if (env.enclClass.sym.isRecord() && (tree.sym.flags_field & RECORD) != 0) { // we are seeing the canonical constructor
1214                         List<Name> recordComponentNames = TreeInfo.recordFields(env.enclClass).map(vd -> vd.sym.name);
1215                         List<Name> initParamNames = tree.sym.params.map(p -> p.name);
1216                         if (!initParamNames.equals(recordComponentNames)) {
1217                             log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1218                                     Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalWithNameMismatch));
1219                         }
1220                         if (tree.sym.type.asMethodType().thrown != null && !tree.sym.type.asMethodType().thrown.isEmpty()) {
1221                             log.error(tree,
1222                                     Errors.InvalidCanonicalConstructorInRecord(
1223                                             TreeInfo.isCompactConstructor(tree) ? Fragments.Compact : Fragments.Canonical,
1224                                             env.enclClass.sym.name,
1225                                             Fragments.ThrowsClauseNotAllowedForCanonicalConstructor(
1226                                                     TreeInfo.isCompactConstructor(tree) ? Fragments.Compact : Fragments.Canonical)));
1227                         }
1228                     }
1229                 }
1230 
1231                 // Attribute all type annotations in the body
1232                 annotate.queueScanTreeAndTypeAnnotate(tree.body, localEnv, m);
1233                 annotate.flush();
1234 
1235                 // Start of constructor prologue (if not in java.lang.Object constructor)
1236                 localEnv.info.ctorPrologue = isConstructor && owner.type != syms.objectType;
1237 
1238                 // Attribute method body.
1239                 attribStat(tree.body, localEnv);
1240                 if (localEnv.info.ctorPrologue) {
1241                     boolean thisInvocation = false;
1242                     ListBuffer<JCTree> prologueCode = new ListBuffer<>();
1243                     for (JCTree stat : tree.body.stats) {
1244                         prologueCode.add(stat);
1245                         /* gather all the stats in the body until a `super` or `this` constructor invocation is found,
1246                          * including the constructor invocation, that way we don't need to worry in the visitor below if
1247                          * if we are dealing or not with prologue code
1248                          */
1249                         if (stat instanceof JCExpressionStatement expStmt &&
1250                                 expStmt.expr instanceof JCMethodInvocation mi &&
1251                                 TreeInfo.isConstructorCall(mi)) {
1252                             thisInvocation = TreeInfo.name(mi.meth) == names._this;
1253                             if (!addedSuperInIdentityClass || !allowValueClasses) {
1254                                 break;
1255                             }
1256                         }
1257                     }
1258                     if (!prologueCode.isEmpty()) {
1259                         CtorPrologueVisitor ctorPrologueVisitor = new CtorPrologueVisitor(localEnv,
1260                                 addedSuperInIdentityClass && allowValueClasses ?
1261                                         PrologueVisitorMode.WARNINGS_ONLY :
1262                                         thisInvocation ?
1263                                                 PrologueVisitorMode.THIS_CONSTRUCTOR :
1264                                                 PrologueVisitorMode.SUPER_CONSTRUCTOR,
1265                                 false);
1266                         ctorPrologueVisitor.scan(prologueCode.toList());
1267                     }
1268                 }
1269             }
1270 
1271             localEnv.info.scope.leave();
1272             result = tree.type = m.type;
1273         } finally {
1274             chk.setLint(prevLint);
1275             chk.setMethod(prevMethod);
1276             env.info.ctorPrologue = ctorProloguePrev;
1277         }
1278     }
1279 
1280     enum PrologueVisitorMode {
1281         WARNINGS_ONLY,
1282         SUPER_CONSTRUCTOR,
1283         THIS_CONSTRUCTOR
1284     }
1285 
1286     class CtorPrologueVisitor extends TreeScanner {
1287         Env<AttrContext> localEnv;
1288         PrologueVisitorMode mode;
1289         boolean isInitializer;
1290 
1291         CtorPrologueVisitor(Env<AttrContext> localEnv, PrologueVisitorMode mode, boolean isInitializer) {
1292             this.localEnv = localEnv;
1293             currentClassSym = localEnv.enclClass.sym;
1294             this.mode = mode;
1295             this.isInitializer = isInitializer;
1296         }
1297 
1298         boolean insideLambdaOrClassDef = false;
1299 
1300         @Override
1301         public void visitLambda(JCLambda lambda) {
1302             boolean previousInsideLambdaOrClassDef = insideLambdaOrClassDef;
1303             try {
1304                 insideLambdaOrClassDef = true;
1305                 super.visitLambda(lambda);
1306             } finally {
1307                 insideLambdaOrClassDef = previousInsideLambdaOrClassDef;
1308             }
1309         }
1310 
1311         ClassSymbol currentClassSym;
1312 
1313         @Override
1314         public void visitClassDef(JCClassDecl classDecl) {
1315             boolean previousInsideLambdaOrClassDef = insideLambdaOrClassDef;
1316             ClassSymbol previousClassSym = currentClassSym;
1317             try {
1318                 insideLambdaOrClassDef = true;
1319                 currentClassSym = classDecl.sym;
1320                 super.visitClassDef(classDecl);
1321             } finally {
1322                 insideLambdaOrClassDef = previousInsideLambdaOrClassDef;
1323                 currentClassSym = previousClassSym;
1324             }
1325         }
1326 
1327         private void reportPrologueError(JCTree tree, Symbol sym) {
1328             reportPrologueError(tree, sym, false);
1329         }
1330 
1331         private void reportPrologueError(JCTree tree, Symbol sym, boolean hasInit) {
1332             preview.checkSourceLevel(tree, Feature.FLEXIBLE_CONSTRUCTORS);
1333             if (mode != PrologueVisitorMode.WARNINGS_ONLY) {
1334                 if (hasInit) {
1335                     log.error(tree, Errors.CantAssignInitializedBeforeCtorCalled(sym));
1336                 } else {
1337                     log.error(tree, Errors.CantRefBeforeCtorCalled(sym));
1338                 }
1339             } else if (allowValueClasses) {
1340                 // issue lint warning
1341                 log.warning(tree, LintWarnings.WouldNotBeAllowedInPrologue(sym));
1342             }
1343         }
1344 
1345         @Override
1346         public void visitApply(JCMethodInvocation tree) {
1347             super.visitApply(tree);
1348             Name name = TreeInfo.name(tree.meth);
1349             boolean isConstructorCall = name == names._this || name == names._super;
1350             Symbol msym = TreeInfo.symbolFor(tree.meth);
1351             // is this an instance method call or an illegal constructor invocation like: `this.super()`?
1352             if (msym != null && // for erroneous invocations msym can be null, ignore those
1353                 (!isConstructorCall ||
1354                 isConstructorCall && tree.meth.hasTag(SELECT))) {
1355                 if (isEarlyReference(localEnv, tree.meth, msym))
1356                     reportPrologueError(tree.meth, msym);
1357             }
1358         }
1359 
1360         @Override
1361         public void visitIdent(JCIdent tree) {
1362             analyzeSymbol(tree);
1363         }
1364 
1365         boolean isIndexed = false;
1366 
1367         @Override
1368         public void visitIndexed(JCArrayAccess tree) {
1369             boolean previousIsIndexed = isIndexed;
1370             try {
1371                 isIndexed = true;
1372                 scan(tree.indexed);
1373             } finally {
1374                 isIndexed = previousIsIndexed;
1375             }
1376             scan(tree.index);
1377             if (mode == PrologueVisitorMode.SUPER_CONSTRUCTOR && isInstanceField(tree.indexed)) {
1378                 localProxyVarsGen.addFieldReadInPrologue(localEnv.enclMethod, TreeInfo.symbolFor(tree.indexed));
1379             }
1380         }
1381 
1382         @Override
1383         public void visitSelect(JCFieldAccess tree) {
1384             SelectScanner ss = new SelectScanner();
1385             ss.scan(tree);
1386             if (ss.scanLater == null) {
1387                 Symbol sym = TreeInfo.symbolFor(tree);
1388                 // if this is a field access
1389                 if (sym.kind == VAR && sym.owner.kind == TYP) {
1390                     // Type.super.field or super.field expressions are forbidden in early construction contexts
1391                     for (JCTree subtree : ss.selectorTrees) {
1392                         if (TreeInfo.isSuperOrSelectorDotSuper(subtree)) {
1393                             reportPrologueError(tree, sym);
1394                             return;
1395                         } else if (mode == PrologueVisitorMode.THIS_CONSTRUCTOR &&
1396                                 TreeInfo.isThisOrSelectorDotThis(subtree) &&
1397                                 TreeInfo.isExplicitThisReference(
1398                                         types,
1399                                         (ClassType)localEnv.enclClass.sym.type,
1400                                         subtree)) {
1401                             reportPrologueError(tree, sym);
1402                             return;
1403                         }
1404                     }
1405                 }
1406                 analyzeSymbol(tree);
1407             } else {
1408                 boolean prevLhs = isInLHS;
1409                 try {
1410                     isInLHS = false;
1411                     scan(ss.scanLater);
1412                 } finally {
1413                     isInLHS = prevLhs;
1414                 }
1415             }
1416             if (mode == PrologueVisitorMode.SUPER_CONSTRUCTOR) {
1417                 for (JCTree subtree : ss.selectorTrees) {
1418                     if (isInstanceField(subtree)) {
1419                         // we need to add a proxy for this one
1420                         localProxyVarsGen.addFieldReadInPrologue(localEnv.enclMethod, TreeInfo.symbolFor(subtree));
1421                     }
1422                 }
1423             }
1424         }
1425 
1426         private boolean isInstanceField(JCTree tree) {
1427             Symbol sym = TreeInfo.symbolFor(tree);
1428             return (sym != null &&
1429                     !sym.isStatic() &&
1430                     sym.kind == VAR &&
1431                     sym.owner.kind == TYP &&
1432                     sym.name != names._this &&
1433                     sym.name != names._super &&
1434                     isEarlyReference(localEnv, tree, sym));
1435         }
1436 
1437         @Override
1438         public void visitNewClass(JCNewClass tree) {
1439             super.visitNewClass(tree);
1440             checkNewClassAndMethRefs(tree, tree.type);
1441         }
1442 
1443         @Override
1444         public void visitReference(JCMemberReference tree) {
1445             super.visitReference(tree);
1446             if (tree.getMode() == JCMemberReference.ReferenceMode.NEW) {
1447                 checkNewClassAndMethRefs(tree, tree.expr.type);
1448             }
1449         }
1450 
1451         void checkNewClassAndMethRefs(JCTree tree, Type t) {
1452             if (t.tsym.isEnclosedBy(localEnv.enclClass.sym) &&
1453                     !t.tsym.isStatic() &&
1454                     !t.tsym.isDirectlyOrIndirectlyLocal()) {
1455                 reportPrologueError(tree, t.getEnclosingType().tsym);
1456             }
1457         }
1458 
1459         /* if a symbol is in the LHS of an assignment expression we won't consider it as a candidate
1460          * for a proxy local variable later on
1461          */
1462         boolean isInLHS = false;
1463 
1464         @Override
1465         public void visitAssign(JCAssign tree) {
1466             boolean previousIsInLHS = isInLHS;
1467             try {
1468                 isInLHS = true;
1469                 scan(tree.lhs);
1470             } finally {
1471                 isInLHS = previousIsInLHS;
1472             }
1473             scan(tree.rhs);
1474         }
1475 
1476         @Override
1477         public void visitMethodDef(JCMethodDecl tree) {
1478             // ignore any declarative part, mainly to avoid scanning receiver parameters
1479             scan(tree.body);
1480         }
1481 
1482         void analyzeSymbol(JCTree tree) {
1483             Symbol sym = TreeInfo.symbolFor(tree);
1484             // make sure that there is a symbol and it is not static
1485             if (sym == null || sym.isStatic()) {
1486                 return;
1487             }
1488             if (isInLHS && !insideLambdaOrClassDef) {
1489                 // Check instance field assignments that appear in constructor prologues
1490                 if (isEarlyReference(localEnv, tree, sym)) {
1491                     // Field may not be inherited from a superclass
1492                     if (sym.owner != localEnv.enclClass.sym) {
1493                         reportPrologueError(tree, sym);
1494                         return;
1495                     }
1496                     // Field may not have an initializer
1497                     if ((sym.flags() & HASINIT) != 0) {
1498                         if (!localEnv.enclClass.sym.isValueClass() || !sym.type.hasTag(ARRAY) || !isIndexed) {
1499                             reportPrologueError(tree, sym, true);
1500                         }
1501                         return;
1502                     }
1503                     // cant reference an instance field before a this constructor
1504                     if (allowValueClasses && mode == PrologueVisitorMode.THIS_CONSTRUCTOR) {
1505                         reportPrologueError(tree, sym);
1506                         return;
1507                     }
1508                 }
1509                 return;
1510             }
1511             tree = TreeInfo.skipParens(tree);
1512             if (sym.kind == VAR && sym.owner.kind == TYP) {
1513                 if (sym.name == names._this || sym.name == names._super) {
1514                     // are we seeing something like `this` or `CurrentClass.this` or `SuperClass.super::foo`?
1515                     if (TreeInfo.isExplicitThisReference(
1516                             types,
1517                             (ClassType)localEnv.enclClass.sym.type,
1518                             tree)) {
1519                         reportPrologueError(tree, sym);
1520                     }
1521                 } else if (sym.kind == VAR && sym.owner.kind == TYP) { // now fields only
1522                     if (sym.owner != localEnv.enclClass.sym) {
1523                         if (localEnv.enclClass.sym.isSubClass(sym.owner, types) &&
1524                                 sym.isInheritedIn(localEnv.enclClass.sym, types)) {
1525                             /* if we are dealing with a field that doesn't belong to the current class, but the
1526                              * field is inherited, this is an error. Unless, the super class is also an outer
1527                              * class and the field's qualifier refers to the outer class
1528                              */
1529                             if (tree.hasTag(IDENT) ||
1530                                 TreeInfo.isExplicitThisReference(
1531                                         types,
1532                                         (ClassType)localEnv.enclClass.sym.type,
1533                                         ((JCFieldAccess)tree).selected)) {
1534                                 reportPrologueError(tree, sym);
1535                             }
1536                         }
1537                     } else if (isEarlyReference(localEnv, tree, sym)) {
1538                         /* now this is a `proper` instance field of the current class
1539                          * references to fields of identity classes which happen to have initializers are
1540                          * not allowed in the prologue.
1541                          * But it is OK for a field with initializer to refer to another field with initializer,
1542                          * so no warning or error if we are analyzing a field initializer.
1543                          */
1544                         if (insideLambdaOrClassDef ||
1545                             (!localEnv.enclClass.sym.isValueClass() &&
1546                              (sym.flags_field & HASINIT) != 0 &&
1547                              !isInitializer))
1548                             reportPrologueError(tree, sym);
1549                         // we will need to generate a proxy for this field later on
1550                         if (!isInLHS) {
1551                             if (!allowValueClasses) {
1552                                 reportPrologueError(tree, sym);
1553                             } else {
1554                                 if (mode == PrologueVisitorMode.THIS_CONSTRUCTOR) {
1555                                     reportPrologueError(tree, sym);
1556                                 } else if (mode == PrologueVisitorMode.SUPER_CONSTRUCTOR && isInstanceField(tree)) {
1557                                     localProxyVarsGen.addFieldReadInPrologue(localEnv.enclMethod, sym);
1558                                 }
1559                                 /* we do nothing in warnings only mode, as in that mode we are simulating what
1560                                  * the compiler would do in case the constructor code would be in the prologue
1561                                  * phase
1562                                  */
1563                             }
1564                         }
1565                     }
1566                 }
1567             }
1568         }
1569 
1570         /**
1571          * Determine if the symbol appearance constitutes an early reference to the current class.
1572          *
1573          * <p>
1574          * This means the symbol is an instance field, or method, of the current class and it appears
1575          * in an early initialization context of it (i.e., one of its constructor prologues).
1576          *
1577          * @param env    The current environment
1578          * @param tree   the AST referencing the variable
1579          * @param sym    The symbol
1580          */
1581         private boolean isEarlyReference(Env<AttrContext> env, JCTree tree, Symbol sym) {
1582             if ((sym.kind == VAR || sym.kind == MTH) &&
1583                     sym.isMemberOf(env.enclClass.sym, types) &&
1584                     ((sym.flags() & STATIC) == 0 ||
1585                     (sym.kind == MTH && tree instanceof JCFieldAccess))) {
1586                 // Allow "Foo.this.x" when "Foo" is (also) an outer class, as this refers to the outer instance
1587                 if (tree instanceof JCFieldAccess fa) {
1588                     return TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, fa.selected);
1589                 } else if (currentClassSym != env.enclClass.sym) {
1590                     /* so we are inside a class, CI, in the prologue of an outer class, CO, and the symbol being
1591                      * analyzed has no qualifier. So if the symbol is a member of CI the reference is allowed,
1592                      * otherwise it is not.
1593                      * It could be that the reference to CI's member happens inside CI's own prologue, but that
1594                      * will be checked separately, when CI's prologue is analyzed.
1595                      */
1596                     return !sym.isMemberOf(currentClassSym, types);
1597                 }
1598                 return true;
1599             }
1600             return false;
1601         }
1602 
1603         /* scanner for a select expression, anything that is not a select or identifier
1604          * will be stored for further analysis
1605          */
1606         class SelectScanner extends DeferredAttr.FilterScanner {
1607             JCTree scanLater;
1608             java.util.List<JCTree> selectorTrees = new ArrayList<>();
1609 
1610             SelectScanner() {
1611                 super(Set.of(IDENT, SELECT, PARENS));
1612             }
1613 
1614             @Override
1615             public void visitSelect(JCFieldAccess tree) {
1616                 super.visitSelect(tree);
1617                 selectorTrees.add(tree.selected);
1618             }
1619 
1620             @Override
1621             void skip(JCTree tree) {
1622                 scanLater = tree;
1623             }
1624         }
1625     }
1626 
1627     public void visitVarDef(JCVariableDecl tree) {
1628         // Local variables have not been entered yet, so we need to do it now:
1629         if (env.info.scope.owner.kind == MTH || env.info.scope.owner.kind == VAR) {
1630             if (tree.sym != null) {
1631                 // parameters have already been entered
1632                 env.info.scope.enter(tree.sym);
1633             } else {
1634                 if (tree.isImplicitlyTyped() && (tree.getModifiers().flags & PARAMETER) == 0) {
1635                     if (tree.init == null) {
1636                         //cannot use 'var' without initializer
1637                         log.error(tree, Errors.CantInferLocalVarType(tree.name, Fragments.LocalMissingInit));
1638                         tree.vartype = make.at(tree.pos()).Erroneous();
1639                     } else {
1640                         Fragment msg = canInferLocalVarType(tree);
1641                         if (msg != null) {
1642                             //cannot use 'var' with initializer which require an explicit target
1643                             //(e.g. lambda, method reference, array initializer).
1644                             log.error(tree, Errors.CantInferLocalVarType(tree.name, msg));
1645                             tree.vartype = make.at(tree.pos()).Erroneous();
1646                         }

1655             }
1656         } else {
1657             doQueueScanTreeAndTypeAnnotateForVarInit(tree, env);
1658         }
1659 
1660         VarSymbol v = tree.sym;
1661         Lint lint = env.info.lint.augment(v);
1662         Lint prevLint = chk.setLint(lint);
1663 
1664         // Check that the variable's declared type is well-formed.
1665         boolean isImplicitLambdaParameter = env.tree.hasTag(LAMBDA) &&
1666                 ((JCLambda)env.tree).paramKind == JCLambda.ParameterKind.IMPLICIT &&
1667                 (tree.sym.flags() & PARAMETER) != 0;
1668         chk.validate(tree.vartype, env, !isImplicitLambdaParameter && !tree.isImplicitlyTyped());
1669 
1670         try {
1671             v.getConstValue(); // ensure compile-time constant initializer is evaluated
1672             chk.checkDeprecatedAnnotation(tree.pos(), v);
1673 
1674             if (tree.init != null) {
1675                 Env<AttrContext> initEnv = memberEnter.initEnv(tree, env);
1676                 if ((v.flags_field & FINAL) == 0 ||
1677                     !memberEnter.needsLazyConstValue(tree.init)) {
1678                     // Not a compile-time constant
1679                     // Attribute initializer in a new environment
1680                     // with the declared variable as owner.
1681                     // Check that initializer conforms to variable's declared type.

1682                     initEnv.info.lint = lint;
1683                     // In order to catch self-references, we set the variable's
1684                     // declaration position to maximal possible value, effectively
1685                     // marking the variable as undefined.
1686                     initEnv.info.enclVar = v;
1687                     boolean previousCtorPrologue = initEnv.info.ctorPrologue;
1688                     try {
1689                         if (v.owner.kind == TYP && !v.isStatic() && v.isStrict()) {
1690                             // strict instance initializer in a value class
1691                             initEnv.info.ctorPrologue = true;
1692                         }
1693                         attribExpr(tree.init, initEnv, v.type);
1694                         if (tree.isImplicitlyTyped()) {
1695                             //fixup local variable type
1696                             v.type = chk.checkLocalVarType(tree, tree.init.type, tree.name);
1697                         }
1698                     } finally {
1699                         initEnv.info.ctorPrologue = previousCtorPrologue;
1700                     }
1701                 }
1702                 if (allowValueClasses && v.owner.kind == TYP && !v.isStatic()) {
1703                     // strict field initializers are inlined in constructor's prologues
1704                     CtorPrologueVisitor ctorPrologueVisitor = new CtorPrologueVisitor(initEnv,
1705                             !v.isStrict() ? PrologueVisitorMode.WARNINGS_ONLY : PrologueVisitorMode.SUPER_CONSTRUCTOR,
1706                             true);
1707                     ctorPrologueVisitor.scan(tree.init);
1708                 }
1709                 if (tree.isImplicitlyTyped()) {
1710                     setSyntheticVariableType(tree, v.type);
1711                 }
1712             }
1713             result = tree.type = v.type;
1714             if (env.enclClass.sym.isRecord() && tree.sym.owner.kind == TYP && !v.isStatic()) {
1715                 if (isNonArgsMethodInObject(v.name)) {
1716                     log.error(tree, Errors.IllegalRecordComponentName(v));
1717                 }
1718             }
1719             chk.checkRequiresIdentity(tree, env.info.lint);
1720         }
1721         finally {
1722             chk.setLint(prevLint);
1723         }
1724     }
1725 
1726     private void doQueueScanTreeAndTypeAnnotateForVarInit(JCVariableDecl tree, Env<AttrContext> env) {
1727         if (tree.init != null &&
1728             (tree.mods.flags & Flags.FIELD_INIT_TYPE_ANNOTATIONS_QUEUED) == 0 &&

1807             }
1808         }
1809     }
1810 
1811     public void visitSkip(JCSkip tree) {
1812         result = null;
1813     }
1814 
1815     public void visitBlock(JCBlock tree) {
1816         if (env.info.scope.owner.kind == TYP || env.info.scope.owner.kind == ERR) {
1817             // Block is a static or instance initializer;
1818             // let the owner of the environment be a freshly
1819             // created BLOCK-method.
1820             Symbol fakeOwner =
1821                 new MethodSymbol(tree.flags | BLOCK |
1822                     env.info.scope.owner.flags() & STRICTFP, names.empty, initBlockType,
1823                     env.info.scope.owner);
1824             final Env<AttrContext> localEnv =
1825                 env.dup(tree, env.info.dup(env.info.scope.dupUnshared(fakeOwner)));
1826 
1827             if ((tree.flags & STATIC) != 0) {
1828                 localEnv.info.staticLevel++;
1829             } else {
1830                 localEnv.info.instanceInitializerBlock = true;
1831             }
1832             // Attribute all type annotations in the block
1833             annotate.queueScanTreeAndTypeAnnotate(tree, localEnv, localEnv.info.scope.owner);
1834             annotate.flush();
1835             attribStats(tree.stats, localEnv);
1836 
1837             {
1838                 // Store init and clinit type annotations with the ClassSymbol
1839                 // to allow output in Gen.normalizeDefs.
1840                 ClassSymbol cs = (ClassSymbol)env.info.scope.owner;
1841                 List<Attribute.TypeCompound> tas = localEnv.info.scope.owner.getRawTypeAttributes();
1842                 if ((tree.flags & STATIC) != 0) {
1843                     cs.appendClassInitTypeAttributes(tas);
1844                 } else {
1845                     cs.appendInitTypeAttributes(tas);
1846                 }
1847             }
1848         } else {
1849             // Create a new local environment with a local scope.
1850             Env<AttrContext> localEnv =
1851                 env.dup(tree, env.info.dup(env.info.scope.dup()));

2324     // where
2325     /** Return the selected enumeration constant symbol, or null. */
2326     private Symbol enumConstant(JCTree tree, Type enumType) {
2327         if (tree.hasTag(IDENT)) {
2328             JCIdent ident = (JCIdent)tree;
2329             Name name = ident.name;
2330             for (Symbol sym : enumType.tsym.members().getSymbolsByName(name)) {
2331                 if (sym.kind == VAR) {
2332                     Symbol s = ident.sym = sym;
2333                     ((VarSymbol)s).getConstValue(); // ensure initializer is evaluated
2334                     ident.type = s.type;
2335                     return ((s.flags_field & Flags.ENUM) == 0)
2336                         ? null : s;
2337                 }
2338             }
2339         }
2340         return null;
2341     }
2342 
2343     public void visitSynchronized(JCSynchronized tree) {
2344         boolean identityType = chk.checkIdentityType(tree.pos(), attribExpr(tree.lock, env));
2345         if (identityType && tree.lock.type != null && tree.lock.type.isValueBased()) {
2346             log.warning(tree.pos(), LintWarnings.AttemptToSynchronizeOnInstanceOfValueBasedClass);
2347         }
2348         attribStat(tree.body, env);
2349         result = null;
2350     }
2351 
2352     public void visitTry(JCTry tree) {
2353         // Create a new local environment with a local
2354         Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
2355         try {
2356             boolean isTryWithResource = tree.resources.nonEmpty();
2357             // Create a nested environment for attributing the try block if needed
2358             Env<AttrContext> tryEnv = isTryWithResource ?
2359                 env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) :
2360                 localEnv;
2361             try {
2362                 // Attribute resource declarations
2363                 for (JCTree resource : tree.resources) {
2364                     CheckContext twrContext = new Check.NestedCheckContext(resultInfo.checkContext) {
2365                         @Override

4781     }
4782 
4783     public void visitSelect(JCFieldAccess tree) {
4784         // Determine the expected kind of the qualifier expression.
4785         KindSelector skind = KindSelector.NIL;
4786         if (tree.name == names._this || tree.name == names._super ||
4787                 tree.name == names._class)
4788         {
4789             skind = KindSelector.TYP;
4790         } else {
4791             if (pkind().contains(KindSelector.PCK))
4792                 skind = KindSelector.of(skind, KindSelector.PCK);
4793             if (pkind().contains(KindSelector.TYP))
4794                 skind = KindSelector.of(skind, KindSelector.TYP, KindSelector.PCK);
4795             if (pkind().contains(KindSelector.VAL_MTH))
4796                 skind = KindSelector.of(skind, KindSelector.VAL, KindSelector.TYP);
4797         }
4798 
4799         // Attribute the qualifier expression, and determine its symbol (if any).
4800         Type site = attribTree(tree.selected, env, new ResultInfo(skind, Type.noType));
4801         Assert.check(site == tree.selected.type);
4802         if (!pkind().contains(KindSelector.TYP_PCK))
4803             site = capture(site); // Capture field access
4804 
4805         // don't allow T.class T[].class, etc
4806         if (skind == KindSelector.TYP) {
4807             Type elt = site;
4808             while (elt.hasTag(ARRAY))
4809                 elt = ((ArrayType)elt).elemtype;
4810             if (elt.hasTag(TYPEVAR)) {
4811                 log.error(tree.pos(), Errors.TypeVarCantBeDeref);
4812                 result = tree.type = types.createErrorType(tree.name, site.tsym, site);
4813                 tree.sym = tree.type.tsym;
4814                 return ;
4815             }
4816         }
4817 
4818         // If qualifier symbol is a type or `super', assert `selectSuper'
4819         // for the selection. This is relevant for determining whether
4820         // protected symbols are accessible.
4821         Symbol sitesym = TreeInfo.symbol(tree.selected);

5893                                                       .filter(s -> s.tsym.isSealed())
5894                                                       .map(s -> (ClassSymbol) s.tsym)
5895                                                       .collect(List.collector());
5896 
5897                 if (sealedSupers.isEmpty()) {
5898                     if ((c.flags_field & Flags.NON_SEALED) != 0) {
5899                         boolean hasErrorSuper = false;
5900 
5901                         hasErrorSuper |= types.directSupertypes(c.type)
5902                                               .stream()
5903                                               .anyMatch(s -> s.tsym.kind == Kind.ERR);
5904 
5905                         ClassType ct = (ClassType) c.type;
5906 
5907                         hasErrorSuper |= !ct.isCompound() && ct.interfaces_field != ct.all_interfaces_field;
5908 
5909                         if (!hasErrorSuper) {
5910                             log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.NonSealedWithNoSealedSupertype(c));
5911                         }
5912                     }
5913                 } else if ((c.flags_field & Flags.COMPOUND) == 0) {
5914                     if (c.isDirectlyOrIndirectlyLocal() && !c.isEnum()) {
5915                         log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.LocalClassesCantExtendSealed(c.isAnonymous() ? Fragments.Anonymous : Fragments.Local));
5916                     }
5917 
5918                     if (!c.type.isCompound()) {
5919                         for (ClassSymbol supertypeSym : sealedSupers) {
5920                             if (!supertypeSym.isPermittedSubclass(c.type.tsym)) {
5921                                 log.error(TreeInfo.diagnosticPositionFor(c.type.tsym, env.tree), Errors.CantInheritFromSealed(supertypeSym));
5922                             }
5923                         }
5924                         if (!c.isNonSealed() && !c.isFinal() && !c.isSealed()) {
5925                             log.error(TreeInfo.diagnosticPositionFor(c, env.tree),
5926                                     c.isInterface() ?
5927                                             Errors.NonSealedOrSealedExpected :
5928                                             Errors.NonSealedSealedOrFinalExpected);
5929                         }
5930                     }
5931                 }
5932 
5933                 env.info.returnResult = null;
5934                 // java.lang.Enum may not be subclassed by a non-enum
5935                 if (st.tsym == syms.enumSym &&
5936                     ((c.flags_field & (Flags.ENUM|Flags.COMPOUND)) == 0))
5937                     log.error(env.tree.pos(), Errors.EnumNoSubclassing);
5938 
5939                 // Enums may not be extended by source-level classes
5940                 if (st.tsym != null &&
5941                     ((st.tsym.flags_field & Flags.ENUM) != 0) &&
5942                     ((c.flags_field & (Flags.ENUM | Flags.COMPOUND)) == 0)) {
5943                     log.error(env.tree.pos(), Errors.EnumTypesNotExtensible);
5944                 }
5945 
5946                 if (rs.isSerializable(c.type)) {
5947                     env.info.isSerializable = true;
5948                 }
5949 
5950                 if (c.isValueClass()) {
5951                     Assert.check(env.tree.hasTag(CLASSDEF));
5952                     chk.checkConstraintsOfValueClass((JCClassDecl) env.tree, c);
5953                 }
5954 
5955                 attribClassBody(env, c);
5956 
5957                 chk.checkDeprecatedAnnotation(env.tree.pos(), c);
5958                 chk.checkClassOverrideEqualsAndHashIfNeeded(env.tree.pos(), c);
5959                 chk.checkFunctionalInterface((JCClassDecl) env.tree, c);
5960                 chk.checkLeaksNotAccessible(env, (JCClassDecl) env.tree);
5961 
5962                 if (c.isImplicit()) {
5963                     chk.checkHasMain(env.tree.pos(), c);
5964                 }
5965             } finally {
5966                 env.info.returnResult = prevReturnRes;
5967                 log.useSource(prev);
5968                 chk.setLint(prevLint);
5969             }
5970 
5971         }
5972     }
5973 
5974     public void visitImport(JCImport tree) {

6081                         sym.kind != VAR ||
6082                         sym.getConstValue() == null)
6083                     log.error(l.head.pos(), Errors.IclsCantHaveStaticDecl(c));
6084             }
6085         }
6086 
6087         // Check for proper placement of super()/this() calls.
6088         chk.checkSuperInitCalls(tree);
6089 
6090         // Check for cycles among non-initial constructors.
6091         chk.checkCyclicConstructors(tree);
6092 
6093         // Check for cycles among annotation elements.
6094         chk.checkNonCyclicElements(tree);
6095 
6096         // Check for proper use of serialVersionUID and other
6097         // serialization-related fields and methods
6098         if (env.info.lint.isEnabled(LintCategory.SERIAL)
6099                 && rs.isSerializable(c.type)
6100                 && !c.isAnonymous()) {
6101             chk.checkSerialStructure(env, tree, c);
6102         }
6103         // Correctly organize the positions of the type annotations
6104         typeAnnotations.organizeTypeAnnotationsBodies(tree);
6105 
6106         // Check type annotations applicability rules
6107         validateTypeAnnotations(tree, false);
6108     }
6109         // where
6110         /** get a diagnostic position for an attribute of Type t, or null if attribute missing */
6111         private DiagnosticPosition getDiagnosticPosition(JCClassDecl tree, Type t) {
6112             for(List<JCAnnotation> al = tree.mods.annotations; !al.isEmpty(); al = al.tail) {
6113                 if (types.isSameType(al.head.annotationType.type, t))
6114                     return al.head.pos();
6115             }
6116 
6117             return null;
6118         }
6119 
6120     private Type capture(Type type) {
6121         return types.capture(type);
< prev index next >