< prev index next > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
Print this page
if ((v.flags() & HASINIT) != 0) {
log.error(pos, Errors.CantAssignInitializedBeforeCtorCalled(v));
return;
}
}
+
+ if (!env.info.ctorPrologue &&
+ v.owner.isValueClass() &&
+ v.owner.kind == TYP &&
+ v.owner == env.enclClass.sym &&
+ (v.flags() & STATIC) == 0 &&
+ (base == null ||
+ TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, base))) {
+ log.error(pos, Errors.CantRefAfterCtorCalled(v));
+ }
}
/** Does tree represent a static reference to an identifier?
* It is assumed that tree is either a SELECT or an IDENT.
* We have to weed out selects from non-type names here.
// or we are compiling class java.lang.Object.
if (isConstructor && owner.type != syms.objectType) {
if (!TreeInfo.hasAnyConstructorCall(tree)) {
JCStatement supCall = make.at(tree.body.pos).Exec(make.Apply(List.nil(),
make.Ident(names._super), make.Idents(List.nil())));
- tree.body.stats = tree.body.stats.prepend(supCall);
+ if (owner.isValueClass()) {
+ tree.body.stats = tree.body.stats.append(supCall);
+ } else {
+ tree.body.stats = tree.body.stats.prepend(supCall);
+ }
} else if ((env.enclClass.sym.flags() & ENUM) != 0 &&
(tree.mods.flags & GENERATEDCONSTR) == 0 &&
TreeInfo.hasConstructorCall(tree, names._super)) {
// enum constructors are not allowed to call super
// directly, so make sure there aren't any super calls
initEnv.info.lint = lint;
// In order to catch self-references, we set the variable's
// declaration position to maximal possible value, effectively
// marking the variable as undefined.
initEnv.info.enclVar = v;
- attribExpr(tree.init, initEnv, v.type);
- if (tree.isImplicitlyTyped()) {
- //fixup local variable type
- v.type = chk.checkLocalVarType(tree, tree.init.type, tree.name);
+ boolean previousCtorPrologue = initEnv.info.ctorPrologue;
+ try {
+ if (v.owner.kind == TYP && v.owner.isValueClass() && !v.isStatic()) {
+ // strict instance initializer in a value class
+ initEnv.info.ctorPrologue = true;
+ }
+ attribExpr(tree.init, initEnv, v.type);
+ if (tree.isImplicitlyTyped()) {
+ //fixup local variable type
+ v.type = chk.checkLocalVarType(tree, tree.init.type, tree.name);
+ }
+ } finally {
+ initEnv.info.ctorPrologue = previousCtorPrologue;
}
}
if (tree.isImplicitlyTyped()) {
setSyntheticVariableType(tree, v.type);
}
env.info.scope.owner.flags() & STRICTFP, names.empty, initBlockType,
env.info.scope.owner);
final Env<AttrContext> localEnv =
env.dup(tree, env.info.dup(env.info.scope.dupUnshared(fakeOwner)));
- if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
+ if ((tree.flags & STATIC) != 0) {
+ localEnv.info.staticLevel++;
+ } else {
+ localEnv.info.instanceInitializerBlock = true;
+ }
// Attribute all type annotations in the block
annotate.queueScanTreeAndTypeAnnotate(tree, localEnv, localEnv.info.scope.owner, null);
annotate.flush();
attribStats(tree.stats, localEnv);
}
return null;
}
public void visitSynchronized(JCSynchronized tree) {
- chk.checkRefType(tree.pos(), attribExpr(tree.lock, env));
- if (env.info.lint.isEnabled(LintCategory.SYNCHRONIZATION) && isValueBased(tree.lock.type)) {
+ boolean identityType = chk.checkIdentityType(tree.pos(), attribExpr(tree.lock, env));
+ if (env.info.lint.isEnabled(LintCategory.SYNCHRONIZATION) &&
+ identityType &&
+ isValueBased(tree.lock.type)) {
log.warning(LintCategory.SYNCHRONIZATION, tree.pos(), Warnings.AttemptToSynchronizeOnInstanceOfValueBasedClass);
}
attribStat(tree.body, env);
result = null;
}
// where
private boolean isValueBased(Type t) {
return t != null && t.tsym != null && (t.tsym.flags() & VALUE_BASED) != 0;
}
-
public void visitTry(JCTry tree) {
// Create a new local environment with a local
Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
try {
boolean isTryWithResource = tree.resources.nonEmpty();
skind = KindSelector.of(skind, KindSelector.VAL, KindSelector.TYP);
}
// Attribute the qualifier expression, and determine its symbol (if any).
Type site = attribTree(tree.selected, env, new ResultInfo(skind, Type.noType));
+ Assert.check(site == tree.selected.type);
if (!pkind().contains(KindSelector.TYP_PCK))
site = capture(site); // Capture field access
// don't allow T.class T[].class, etc
if (skind == KindSelector.TYP) {
if (!hasErrorSuper) {
log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.NonSealedWithNoSealedSupertype(c));
}
}
- } else {
+ } else if ((c.flags_field & Flags.COMPOUND) == 0) {
if (c.isDirectlyOrIndirectlyLocal() && !c.isEnum()) {
log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.LocalClassesCantExtendSealed(c.isAnonymous() ? Fragments.Anonymous : Fragments.Local));
}
if (!c.type.isCompound()) {
if (rs.isSerializable(c.type)) {
env.info.isSerializable = true;
}
+ if (c.isValueClass()) {
+ Assert.check(env.tree.hasTag(CLASSDEF));
+ chk.checkConstraintsOfValueClass((JCClassDecl) env.tree, c);
+ }
+
attribClassBody(env, c);
chk.checkDeprecatedAnnotation(env.tree.pos(), c);
chk.checkClassOverrideEqualsAndHashIfNeeded(env.tree.pos(), c);
chk.checkFunctionalInterface((JCClassDecl) env.tree, c);
// Check for proper use of serialVersionUID and other
// serialization-related fields and methods
if (env.info.lint.isEnabled(LintCategory.SERIAL)
&& rs.isSerializable(c.type)
&& !c.isAnonymous()) {
- chk.checkSerialStructure(tree, c);
+ chk.checkSerialStructure(env, tree, c);
}
// Correctly organize the positions of the type annotations
typeAnnotations.organizeTypeAnnotationsBodies(tree);
// Check type annotations applicability rules
< prev index next >