src/share/classes/com/sun/tools/javac/comp/Attr.java
Print this page
*** 37,46 ****
--- 37,47 ----
import com.sun.source.util.SimpleTreeVisitor;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Lint.LintCategory;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.*;
+ import com.sun.tools.javac.code.TypeAnnotationPosition.*;
import com.sun.tools.javac.comp.Check.CheckContext;
import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
import com.sun.tools.javac.comp.Infer.InferenceContext;
import com.sun.tools.javac.comp.Infer.FreeTypeListener;
import com.sun.tools.javac.jvm.*;
*** 92,101 ****
--- 93,105 ----
final JCDiagnostic.Factory diags;
final Annotate annotate;
final TypeAnnotations typeAnnotations;
final DeferredLintHandler deferredLintHandler;
+ /** The creator that will be used for any varDef's we visit. */
+ Annotate.PositionCreator creator;
+
public static Attr instance(Context context) {
Attr instance = context.get(attrKey);
if (instance == null)
instance = new Attr(context);
return instance;
*** 120,129 ****
--- 124,135 ----
types = Types.instance(context);
diags = JCDiagnostic.Factory.instance(context);
annotate = Annotate.instance(context);
typeAnnotations = TypeAnnotations.instance(context);
deferredLintHandler = DeferredLintHandler.instance(context);
+ creator = null;
+ speculative = false;
Options options = Options.instance(context);
Source source = Source.instance(context);
allowGenerics = source.allowGenerics();
*** 229,238 ****
--- 235,249 ----
/**
* Switch: name of source level; used for error reporting.
*/
String sourceName;
+ /**
+ * Whether or not this is speculative attribution
+ */
+ boolean speculative;
+
/** Check kind and type of given tree against protokind and prototype.
* If check succeeds, store type in tree and return it.
* If check fails, store errType in tree and return it.
* No checks are performed if the prototype is a method type.
* It is not necessary in this case since we know that kind and type
*** 423,445 ****
public Type coerce(Type etype, Type ttype) {
return cfolder.coerce(etype, ttype);
}
! public Type attribType(JCTree node, TypeSymbol sym) {
Env<AttrContext> env = enter.typeEnvs.get(sym);
Env<AttrContext> localEnv = env.dup(node, env.info.dup());
! return attribTree(node, localEnv, unknownTypeInfo);
}
! public Type attribImportQualifier(JCImport tree, Env<AttrContext> env) {
// Attribute qualifying package or class.
JCFieldAccess s = (JCFieldAccess)tree.qualid;
! return attribTree(s.selected,
! env,
new ResultInfo(tree.staticImport ? TYP : (TYP | PCK),
! Type.noType));
}
public Env<AttrContext> attribExprToTree(JCTree expr, Env<AttrContext> env, JCTree tree) {
breakTree = tree;
JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
--- 434,462 ----
public Type coerce(Type etype, Type ttype) {
return cfolder.coerce(etype, ttype);
}
! public Type attribType(JCTree node, TypeSymbol sym,
! JCLambda currentLambda, boolean speculative) {
Env<AttrContext> env = enter.typeEnvs.get(sym);
Env<AttrContext> localEnv = env.dup(node, env.info.dup());
! return attribTree(node, localEnv, currentLambda,
! unknownTypeInfo, speculative);
}
! public Type attribType(JCTree node, TypeSymbol sym) {
! return attribType(node, sym, currentLambda, speculative);
! }
!
! public Type attribImportQualifier(JCImport tree, Env<AttrContext> env,
! JCLambda currLambda, boolean speculative) {
// Attribute qualifying package or class.
JCFieldAccess s = (JCFieldAccess)tree.qualid;
! return attribTree(s.selected, env, currentLambda,
new ResultInfo(tree.staticImport ? TYP : (TYP | PCK),
! Type.noType), speculative);
}
public Env<AttrContext> attribExprToTree(JCTree expr, Env<AttrContext> env, JCTree tree) {
breakTree = tree;
JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
*** 569,578 ****
--- 586,597 ----
/** Visitor argument: the current environment.
*/
Env<AttrContext> env;
+ JCLambda currentLambda;
+
/** Visitor argument: the currently expected attribution result.
*/
ResultInfo resultInfo;
/** Visitor result: the computed type.
*** 584,599 ****
*
* @param tree The tree to be visited.
* @param env The environment visitor argument.
* @param resultInfo The result info visitor argument.
*/
! Type attribTree(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) {
Env<AttrContext> prevEnv = this.env;
ResultInfo prevResult = this.resultInfo;
try {
this.env = env;
this.resultInfo = resultInfo;
tree.accept(this);
if (tree == breakTree &&
resultInfo.checkContext.deferredAttrContext().mode == AttrMode.CHECK) {
throw new BreakAttr(copyEnv(env));
}
--- 603,624 ----
*
* @param tree The tree to be visited.
* @param env The environment visitor argument.
* @param resultInfo The result info visitor argument.
*/
! Type attribTree(JCTree tree, Env<AttrContext> env,
! JCLambda lambda, ResultInfo resultInfo,
! boolean speculative) {
Env<AttrContext> prevEnv = this.env;
ResultInfo prevResult = this.resultInfo;
+ JCLambda prevLambda = this.currentLambda;
+ boolean prevSpeculative = this.speculative;
try {
this.env = env;
this.resultInfo = resultInfo;
+ this.currentLambda = lambda;
+ this.speculative = speculative;
tree.accept(this);
if (tree == breakTree &&
resultInfo.checkContext.deferredAttrContext().mode == AttrMode.CHECK) {
throw new BreakAttr(copyEnv(env));
}
*** 602,612 ****
--- 627,648 ----
tree.type = syms.errType;
return chk.completionError(tree.pos(), ex);
} finally {
this.env = prevEnv;
this.resultInfo = prevResult;
+ this.currentLambda = prevLambda;
+ this.speculative = prevSpeculative;
+ }
}
+
+ Type attribTree(JCTree tree, Env<AttrContext> env,
+ JCLambda currentLambda, ResultInfo resultInfo) {
+ return attribTree(tree, env, currentLambda, resultInfo, speculative);
+ }
+
+ Type attribTree(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) {
+ return attribTree(tree, env, currentLambda, resultInfo, speculative);
}
Env<AttrContext> copyEnv(Env<AttrContext> env) {
Env<AttrContext> newEnv =
env.dup(env.tree, env.info.dup(copyScope(env.info.scope)));
*** 631,682 ****
return newScope;
}
/** Derived visitor method: attribute an expression tree.
*/
public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt) {
! return attribTree(tree, env, new ResultInfo(VAL, !pt.hasTag(ERROR) ? pt : Type.noType));
}
/** Derived visitor method: attribute an expression tree with
* no constraints on the computed type.
*/
public Type attribExpr(JCTree tree, Env<AttrContext> env) {
! return attribTree(tree, env, unknownExprInfo);
}
/** Derived visitor method: attribute a type tree.
*/
public Type attribType(JCTree tree, Env<AttrContext> env) {
! Type result = attribType(tree, env, Type.noType);
return result;
}
/** Derived visitor method: attribute a type tree.
*/
! Type attribType(JCTree tree, Env<AttrContext> env, Type pt) {
! Type result = attribTree(tree, env, new ResultInfo(TYP, pt));
return result;
}
/** Derived visitor method: attribute a statement or definition tree.
*/
public Type attribStat(JCTree tree, Env<AttrContext> env) {
! return attribTree(tree, env, statInfo);
}
/** Attribute a list of expressions, returning a list of types.
*/
List<Type> attribExprs(List<JCExpression> trees, Env<AttrContext> env, Type pt) {
ListBuffer<Type> ts = new ListBuffer<>();
for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail)
! ts.append(attribExpr(l.head, env, pt));
return ts.toList();
}
/** Attribute a list of statements, returning nothing.
*/
<T extends JCTree> void attribStats(List<T> trees, Env<AttrContext> env) {
for (List<T> l = trees; l.nonEmpty(); l = l.tail)
attribStat(l.head, env);
}
--- 667,761 ----
return newScope;
}
/** Derived visitor method: attribute an expression tree.
*/
+ public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt,
+ JCLambda currentLambda, boolean speculative) {
+ return attribTree(tree, env, currentLambda,
+ new ResultInfo(VAL, !pt.hasTag(ERROR) ? pt : Type.noType),
+ speculative);
+ }
+
public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt) {
! return attribExpr(tree, env, pt, currentLambda, speculative);
}
/** Derived visitor method: attribute an expression tree with
* no constraints on the computed type.
*/
public Type attribExpr(JCTree tree, Env<AttrContext> env) {
! return attribTree(tree, env, currentLambda,
! unknownExprInfo, speculative);
}
/** Derived visitor method: attribute a type tree.
*/
+
public Type attribType(JCTree tree, Env<AttrContext> env) {
! Type result = attribType(tree, env, Type.noType,
! currentLambda, speculative);
! return result;
! }
!
! public Type attribType(JCTree tree, Env<AttrContext> env,
! JCLambda currentLambda, boolean speculative) {
! Type result = attribType(tree, env, Type.noType,
! currentLambda, speculative);
return result;
}
/** Derived visitor method: attribute a type tree.
*/
! Type attribType(JCTree tree, Env<AttrContext> env, Type pt,
! JCLambda currentLambda, boolean speculative) {
! Type result = attribTree(tree, env, currentLambda,
! new ResultInfo(TYP, pt), speculative);
return result;
}
/** Derived visitor method: attribute a statement or definition tree.
*/
+
public Type attribStat(JCTree tree, Env<AttrContext> env) {
! return attribTree(tree, env, currentLambda, statInfo, speculative);
! }
!
! public Type attribStat(JCTree tree, JCLambda lambda,
! Env<AttrContext> env) {
! return attribTree(tree, env, lambda, statInfo, speculative);
! }
!
! public Type attribStat(JCTree tree, JCLambda lambda,
! Env<AttrContext> env, boolean speculative) {
! return attribTree(tree, env, lambda, statInfo, speculative);
}
/** Attribute a list of expressions, returning a list of types.
*/
List<Type> attribExprs(List<JCExpression> trees, Env<AttrContext> env, Type pt) {
ListBuffer<Type> ts = new ListBuffer<>();
for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail)
! ts.append(attribExpr(l.head, env, pt, currentLambda, speculative));
return ts.toList();
}
/** Attribute a list of statements, returning nothing.
*/
+ <T extends JCTree> void attribStats(List<T> trees, JCLambda lambda,
+ Env<AttrContext> env,
+ boolean speculative) {
+ for (List<T> l = trees; l.nonEmpty(); l = l.tail)
+ attribStat(l.head, lambda, env, speculative);
+ }
+
+ <T extends JCTree> void attribStats(List<T> trees, JCLambda lambda,
+ Env<AttrContext> env) {
+ for (List<T> l = trees; l.nonEmpty(); l = l.tail)
+ attribStat(l.head, lambda, env);
+ }
+
<T extends JCTree> void attribStats(List<T> trees, Env<AttrContext> env) {
for (List<T> l = trees; l.nonEmpty(); l = l.tail)
attribStat(l.head, env);
}
*** 684,698 ****
*/
int attribArgs(List<JCExpression> trees, Env<AttrContext> env, ListBuffer<Type> argtypes) {
int kind = VAL;
for (JCExpression arg : trees) {
Type argtype;
! if (allowPoly && deferredAttr.isDeferred(env, arg)) {
! argtype = deferredAttr.new DeferredType(arg, env);
kind |= POLY;
} else {
! argtype = chk.checkNonVoid(arg, attribTree(arg, env, unknownAnyPolyInfo));
}
argtypes.append(argtype);
}
return kind;
}
--- 763,778 ----
*/
int attribArgs(List<JCExpression> trees, Env<AttrContext> env, ListBuffer<Type> argtypes) {
int kind = VAL;
for (JCExpression arg : trees) {
Type argtype;
! if (allowPoly && deferredAttr.isDeferred(env, arg, currentLambda)) {
! argtype = deferredAttr.new DeferredType(arg, env, currentLambda,
! annotate.noCreator);
kind |= POLY;
} else {
! argtype = chk.checkNonVoid(arg, attribTree(arg, env, currentLambda, unknownAnyPolyInfo, speculative));
}
argtypes.append(argtype);
}
return kind;
}
*** 719,737 ****
* Attribute type variables (of generic classes or methods).
* Compound types are attributed later in attribBounds.
* @param typarams the type variables to enter
* @param env the current environment
*/
! void attribTypeVariables(List<JCTypeParameter> typarams, Env<AttrContext> env) {
for (JCTypeParameter tvar : typarams) {
TypeVar a = (TypeVar)tvar.type;
a.tsym.flags_field |= UNATTRIBUTED;
a.bound = Type.noType;
if (!tvar.bounds.isEmpty()) {
! List<Type> bounds = List.of(attribType(tvar.bounds.head, env));
for (JCExpression bound : tvar.bounds.tail)
! bounds = bounds.prepend(attribType(bound, env));
types.setBounds(a, bounds.reverse());
} else {
// if no bounds are given, assume a single bound of
// java.lang.Object.
types.setBounds(a, List.of(syms.objectType));
--- 799,821 ----
* Attribute type variables (of generic classes or methods).
* Compound types are attributed later in attribBounds.
* @param typarams the type variables to enter
* @param env the current environment
*/
! void attribTypeVariables(List<JCTypeParameter> typarams, Env<AttrContext> env,
! JCLambda currentLambda, boolean speculative) {
for (JCTypeParameter tvar : typarams) {
TypeVar a = (TypeVar)tvar.type;
a.tsym.flags_field |= UNATTRIBUTED;
a.bound = Type.noType;
if (!tvar.bounds.isEmpty()) {
! List<Type> bounds =
! List.of(attribType(tvar.bounds.head, env,
! currentLambda, speculative));
for (JCExpression bound : tvar.bounds.tail)
! bounds = bounds.prepend(attribType(bound, env, currentLambda,
! speculative));
types.setBounds(a, bounds.reverse());
} else {
// if no bounds are given, assume a single bound of
// java.lang.Object.
types.setBounds(a, List.of(syms.objectType));
*** 745,777 ****
/**
* Attribute the type references in a list of annotations.
*/
void attribAnnotationTypes(List<JCAnnotation> annotations,
! Env<AttrContext> env) {
for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
JCAnnotation a = al.head;
! attribType(a.annotationType, env);
}
}
/**
* Attribute a "lazy constant value".
* @param env The env for the const value
* @param initializer The initializer for the const value
* @param type The expected type, or null
* @see VarSymbol#setLazyConstValue
*/
! public Object attribLazyConstantValue(Env<AttrContext> env,
JCVariableDecl variable,
! Type type) {
DiagnosticPosition prevLintPos
= deferredLintHandler.setPos(variable.pos());
try {
! Type itype = attribExpr(variable.init, env, type);
if (itype.constValue() != null) {
return coerce(itype, type).constValue();
} else {
return null;
}
--- 829,871 ----
/**
* Attribute the type references in a list of annotations.
*/
void attribAnnotationTypes(List<JCAnnotation> annotations,
! Env<AttrContext> env,
! JCLambda currentLambda,
! boolean speculative) {
for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
JCAnnotation a = al.head;
! attribType(a.annotationType, env, currentLambda, speculative);
! }
}
+
+ void attribAnnotationTypes(List<JCAnnotation> annotations,
+ Env<AttrContext> env) {
+ attribAnnotationTypes(annotations, env, currentLambda, speculative);
}
/**
* Attribute a "lazy constant value".
* @param env The env for the const value
* @param initializer The initializer for the const value
* @param type The expected type, or null
* @see VarSymbol#setLazyConstValue
*/
! public Object attribLazyConstantValue(final Env<AttrContext> env,
JCVariableDecl variable,
! Type type,
! JCLambda currentLambda,
! boolean speculative) {
DiagnosticPosition prevLintPos
= deferredLintHandler.setPos(variable.pos());
try {
! Type itype = attribExpr(variable.init, env, type,
! currentLambda, speculative);
if (itype.constValue() != null) {
return coerce(itype, type).constValue();
} else {
return null;
}
*** 790,803 ****
*/
Type attribBase(JCTree tree,
Env<AttrContext> env,
boolean classExpected,
boolean interfaceExpected,
! boolean checkExtensible) {
Type t = tree.type != null ?
tree.type :
! attribType(tree, env);
return checkBase(t, tree, env, classExpected, interfaceExpected, checkExtensible);
}
Type checkBase(Type t,
JCTree tree,
Env<AttrContext> env,
--- 884,899 ----
*/
Type attribBase(JCTree tree,
Env<AttrContext> env,
boolean classExpected,
boolean interfaceExpected,
! boolean checkExtensible,
! JCLambda currentLambda,
! boolean speculative) {
Type t = tree.type != null ?
tree.type :
! attribType(tree, env, currentLambda, speculative);
return checkBase(t, tree, env, classExpected, interfaceExpected, checkExtensible);
}
Type checkBase(Type t,
JCTree tree,
Env<AttrContext> env,
*** 878,887 ****
--- 974,984 ----
((JCNewClass) env.tree).encl == null)
{
c.flags_field |= NOOUTERTHIS;
}
attribClass(tree.pos(), c);
+
result = tree.type = c.type;
}
}
public void visitMethodDef(JCMethodDecl tree) {
*** 1015,1028 ****
"call.to.super.not.allowed.in.enum.ctor",
env.enclClass.sym);
}
}
- // Attribute all type annotations in the body
- annotate.annotateTypeLater(tree.body, localEnv, m, null);
- annotate.flush();
-
// Attribute method body.
attribStat(tree.body, localEnv);
}
localEnv.info.scope.leave();
--- 1112,1121 ----
*** 1032,1056 ****
chk.setLint(prevLint);
chk.setMethod(prevMethod);
}
}
! public void visitVarDef(JCVariableDecl tree) {
// Local variables have not been entered yet, so we need to do it now:
if (env.info.scope.owner.kind == MTH) {
if (tree.sym != null) {
// parameters have already been entered
env.info.scope.enter(tree.sym);
} else {
! memberEnter.memberEnter(tree, env);
! annotate.flush();
}
! } else {
! if (tree.init != null) {
! // Field initializer expression need to be entered.
! annotate.annotateTypeLater(tree.init, env, tree.sym, tree.pos());
annotate.flush();
}
}
VarSymbol v = tree.sym;
Lint lint = env.info.lint.augment(v);
--- 1125,1153 ----
chk.setLint(prevLint);
chk.setMethod(prevMethod);
}
}
! public void visitVarDef(final JCVariableDecl tree) {
// Local variables have not been entered yet, so we need to do it now:
if (env.info.scope.owner.kind == MTH) {
if (tree.sym != null) {
// parameters have already been entered
env.info.scope.enter(tree.sym);
} else {
! Annotate.PositionCreator oldcreator = creator;
!
! if (creator == null) {
! creator = annotate.localVarCreator(tree.pos);
}
!
! annotate.enterStart();
! memberEnter.memberEnter(tree, env, creator,
! currentLambda, speculative);
! annotate.enterDone();
annotate.flush();
+ creator = oldcreator;
}
}
VarSymbol v = tree.sym;
Lint lint = env.info.lint.augment(v);
*** 1097,1117 ****
public void visitBlock(JCBlock tree) {
if (env.info.scope.owner.kind == TYP) {
// Block is a static or instance initializer;
// let the owner of the environment be a freshly
// created BLOCK-method.
! Env<AttrContext> localEnv =
env.dup(tree, env.info.dup(env.info.scope.dupUnshared()));
localEnv.info.scope.owner =
new MethodSymbol(tree.flags | BLOCK |
env.info.scope.owner.flags() & STRICTFP, names.empty, null,
env.info.scope.owner);
- if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
! // Attribute all type annotations in the block
! annotate.annotateTypeLater(tree, localEnv, localEnv.info.scope.owner, null);
! annotate.flush();
{
// Store init and clinit type annotations with the ClassSymbol
// to allow output in Gen.normalizeDefs.
ClassSymbol cs = (ClassSymbol)env.info.scope.owner;
--- 1194,1212 ----
public void visitBlock(JCBlock tree) {
if (env.info.scope.owner.kind == TYP) {
// Block is a static or instance initializer;
// let the owner of the environment be a freshly
// created BLOCK-method.
! final Env<AttrContext> localEnv =
env.dup(tree, env.info.dup(env.info.scope.dupUnshared()));
localEnv.info.scope.owner =
new MethodSymbol(tree.flags | BLOCK |
env.info.scope.owner.flags() & STRICTFP, names.empty, null,
env.info.scope.owner);
! if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
! attribStats(tree.stats, localEnv);
{
// Store init and clinit type annotations with the ClassSymbol
// to allow output in Gen.normalizeDefs.
ClassSymbol cs = (ClassSymbol)env.info.scope.owner;
*** 1120,1131 ****
cs.appendClassInitTypeAttributes(tas);
} else {
cs.appendInitTypeAttributes(tas);
}
}
-
- attribStats(tree.stats, localEnv);
} else {
// Create a new local environment with a local scope.
Env<AttrContext> localEnv =
env.dup(tree, env.info.dup(env.info.scope.dup()));
try {
--- 1215,1224 ----
*** 1344,1354 ****
--- 1437,1450 ----
chk.basicHandler.report(pos, diags.fragment("try.not.applicable.to.type", details));
}
};
ResultInfo twrResult = new ResultInfo(VAL, syms.autoCloseableType, twrContext);
if (resource.hasTag(VARDEF)) {
+ Annotate.PositionCreator oldcreator = creator;
+ creator = annotate.resourceVarCreator(tree.pos);
attribStat(resource, tryEnv);
+ creator = oldcreator;
twrResult.check(resource, resource.type);
//check that resource type cannot throw InterruptedException
checkAutoCloseable(resource.pos(), localEnv, resource.type);
*** 1369,1379 ****
--- 1465,1478 ----
for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
JCCatch c = l.head;
Env<AttrContext> catchEnv =
localEnv.dup(c, localEnv.info.dup(localEnv.info.scope.dup()));
try {
+ Annotate.PositionCreator oldcreator = creator;
+ creator = annotate.exceptionParamCreator(tree.pos);
Type ctype = attribStat(c.param, catchEnv);
+ creator = oldcreator;
if (TreeInfo.isMultiCatch(c)) {
//multi-catch parameter is implicitly marked as final
c.param.sym.flags_field |= FINAL | UNION;
}
if (c.param.sym.kind == Kinds.VAR) {
*** 1475,1495 ****
JCConditional condTree = (JCConditional)tree;
return isBooleanOrNumeric(env, condTree.truepart) &&
isBooleanOrNumeric(env, condTree.falsepart);
case APPLY:
JCMethodInvocation speculativeMethodTree =
! (JCMethodInvocation)deferredAttr.attribSpeculative(tree, env, unknownExprInfo);
Type owntype = TreeInfo.symbol(speculativeMethodTree.meth).type.getReturnType();
return types.unboxedTypeOrType(owntype).isPrimitive();
case NEWCLASS:
JCExpression className =
removeClassParams.translate(((JCNewClass)tree).clazz);
JCExpression speculativeNewClassTree =
! (JCExpression)deferredAttr.attribSpeculative(className, env, unknownTypeInfo);
return types.unboxedTypeOrType(speculativeNewClassTree.type).isPrimitive();
default:
! Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo).type;
speculativeType = types.unboxedTypeOrType(speculativeType);
return speculativeType.isPrimitive();
}
}
//where
--- 1574,1599 ----
JCConditional condTree = (JCConditional)tree;
return isBooleanOrNumeric(env, condTree.truepart) &&
isBooleanOrNumeric(env, condTree.falsepart);
case APPLY:
JCMethodInvocation speculativeMethodTree =
! (JCMethodInvocation)deferredAttr.attribSpeculative(tree, env, unknownExprInfo,
! currentLambda, annotate.noCreator);
Type owntype = TreeInfo.symbol(speculativeMethodTree.meth).type.getReturnType();
return types.unboxedTypeOrType(owntype).isPrimitive();
case NEWCLASS:
JCExpression className =
removeClassParams.translate(((JCNewClass)tree).clazz);
JCExpression speculativeNewClassTree =
! (JCExpression)deferredAttr.attribSpeculative(className,
! env,
! unknownTypeInfo,
! currentLambda,
! annotate.newObjCreator(tree.pos));
return types.unboxedTypeOrType(speculativeNewClassTree.type).isPrimitive();
default:
! Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo, currentLambda, annotate.noCreator).type;
speculativeType = types.unboxedTypeOrType(speculativeType);
return speculativeType.isPrimitive();
}
}
//where
*** 1748,1758 ****
localEnv.info.isSelfCall = true;
// Attribute arguments, yielding list of argument types.
attribArgs(tree.args, localEnv, argtypesBuf);
argtypes = argtypesBuf.toList();
! typeargtypes = attribTypes(tree.typeargs, localEnv);
// Variable `site' points to the class in which the called
// constructor is defined.
Type site = env.enclClass.sym.type;
if (methName == names._super) {
--- 1852,1882 ----
localEnv.info.isSelfCall = true;
// Attribute arguments, yielding list of argument types.
attribArgs(tree.args, localEnv, argtypesBuf);
argtypes = argtypesBuf.toList();
!
! // Attribute and annotate the type arguments
! ListBuffer<Type> typeargtypesbuf = new ListBuffer<>();
! int i = 0;
!
! for (List<JCExpression> l = tree.typeargs;
! l.nonEmpty(); l = l.tail, i++) {
! final JCExpression arg = l.head;
! annotate.enterStart();
! typeargtypesbuf.append(attribType(arg, localEnv));
! annotate.annotateTypeLater(arg, localEnv,
! localEnv.info.scope.owner,
! tree.pos(), currentLambda,
! annotate.constructorInvokeTypeArgCreator(i, tree.pos),
! speculative);
! annotate.enterDone();
! annotate.flush();
! }
!
! typeargtypes =
! chk.checkRefTypes(tree.typeargs, typeargtypesbuf.toList());
// Variable `site' points to the class in which the called
// constructor is defined.
Type site = env.enclClass.sym.type;
if (methName == names._super) {
*** 1821,1831 ****
} else {
// Otherwise, we are seeing a regular method call.
// Attribute the arguments, yielding list of argument types, ...
int kind = attribArgs(tree.args, localEnv, argtypesBuf);
argtypes = argtypesBuf.toList();
! typeargtypes = attribAnyTypes(tree.typeargs, localEnv);
// ... and attribute the method using as a prototype a methodtype
// whose formal argument types is exactly the list of actual
// arguments (this will also set the method symbol).
Type mpt = newMethodTemplate(resultInfo.pt, argtypes, typeargtypes);
--- 1945,1974 ----
} else {
// Otherwise, we are seeing a regular method call.
// Attribute the arguments, yielding list of argument types, ...
int kind = attribArgs(tree.args, localEnv, argtypesBuf);
argtypes = argtypesBuf.toList();
!
! // Attribute and annotate the type arguments
! ListBuffer<Type> typeargtypesbuf = new ListBuffer<>();
! int i = 0;
!
! for (List<JCExpression> l = tree.typeargs;
! l.nonEmpty(); l = l.tail, i++) {
! final JCExpression arg = l.head;
! annotate.enterStart();
! typeargtypesbuf.append(attribType(arg, localEnv));
! annotate.annotateTypeLater(arg, localEnv,
! localEnv.info.scope.owner,
! tree.pos(), currentLambda,
! annotate.methodInvokeTypeArgCreator(i, tree.pos),
! speculative);
! annotate.flush();
! annotate.enterDone();
! }
!
! typeargtypes = typeargtypesbuf.toList();
// ... and attribute the method using as a prototype a methodtype
// whose formal argument types is exactly the list of actual
// arguments (this will also set the method symbol).
Type mpt = newMethodTemplate(resultInfo.pt, argtypes, typeargtypes);
*** 1846,1855 ****
--- 1989,1999 ----
// Check that value of resulting type is admissible in the
// current context. Also, capture the return type
result = check(tree, capture(restype), VAL, resultInfo);
}
+
chk.validate(tree.typeargs, localEnv);
}
//where
Type adjustMethodReturnType(Type qualifierType, Name methodName, List<Type> argtypes, Type restype) {
if (allowCovariantReturns &&
*** 1921,1938 ****
clazzid = ((JCTypeApply) clazz).clazz;
if (clazzid.hasTag(ANNOTATED_TYPE)) {
annoclazzid = (JCAnnotatedType) clazzid;
clazzid = annoclazzid.underlyingType;
}
! } else {
! if (clazz.hasTag(ANNOTATED_TYPE)) {
annoclazzid = (JCAnnotatedType) clazz;
clazzid = annoclazzid.underlyingType;
} else {
clazzid = clazz;
}
- }
JCExpression clazzid1 = clazzid; // The same in fully qualified form
if (tree.encl != null) {
// We are seeing a qualified new, of the form
--- 2065,2080 ----
clazzid = ((JCTypeApply) clazz).clazz;
if (clazzid.hasTag(ANNOTATED_TYPE)) {
annoclazzid = (JCAnnotatedType) clazzid;
clazzid = annoclazzid.underlyingType;
}
! } else if (clazz.hasTag(ANNOTATED_TYPE)) {
annoclazzid = (JCAnnotatedType) clazz;
clazzid = annoclazzid.underlyingType;
} else {
clazzid = clazz;
}
JCExpression clazzid1 = clazzid; // The same in fully qualified form
if (tree.encl != null) {
// We are seeing a qualified new, of the form
*** 1950,1964 ****
clazzid1 = make.at(clazz.pos).Select(make.Type(encltype),
((JCIdent) clazzid).name);
EndPosTable endPosTable = this.env.toplevel.endPositions;
endPosTable.storeEnd(clazzid1, tree.getEndPosition(endPosTable));
! if (clazz.hasTag(ANNOTATED_TYPE)) {
! JCAnnotatedType annoType = (JCAnnotatedType) clazz;
! List<JCAnnotation> annos = annoType.annotations;
- if (annoType.underlyingType.hasTag(TYPEAPPLY)) {
clazzid1 = make.at(tree.pos).
TypeApply(clazzid1,
((JCTypeApply) clazz).arguments);
}
--- 2092,2107 ----
clazzid1 = make.at(clazz.pos).Select(make.Type(encltype),
((JCIdent) clazzid).name);
EndPosTable endPosTable = this.env.toplevel.endPositions;
endPosTable.storeEnd(clazzid1, tree.getEndPosition(endPosTable));
! if (annoclazzid != null) {
! JCAnnotatedType annoType = annoclazzid;
! List<JCAnnotation> annos = annoclazzid.annotations;
!
! if (clazz.hasTag(TYPEAPPLY)) {
clazzid1 = make.at(tree.pos).
TypeApply(clazzid1,
((JCTypeApply) clazz).arguments);
}
*** 1971,1986 ****
--- 2114,2136 ----
}
clazz = clazzid1;
}
+ annotate.enterStart();
// Attribute clazz expression and store
// symbol + type back into the attributed tree.
Type clazztype = TreeInfo.isEnumInit(env.tree) ?
attribIdentAsEnumType(env, (JCIdent)clazz) :
attribType(clazz, env);
+ annotate.annotateTypeLater(clazz, env, env.info.scope.owner,
+ tree.pos(), currentLambda,
+ annotate.newObjCreator(tree.pos),
+ speculative);
+ annotate.enterDone();
+ annotate.flush();
clazztype = chk.checkDiamond(tree, clazztype);
chk.validate(clazz, localEnv);
if (tree.encl != null) {
// We have to work in this case to store
// symbol + type back into the attributed tree.
*** 2005,2015 ****
// Attribute constructor arguments.
ListBuffer<Type> argtypesBuf = new ListBuffer<>();
int pkind = attribArgs(tree.args, localEnv, argtypesBuf);
List<Type> argtypes = argtypesBuf.toList();
! List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv);
// If we have made no mistakes in the class type...
if (clazztype.hasTag(CLASS)) {
// Enums may not be instantiated except implicitly
if (allowEnums &&
--- 2155,2185 ----
// Attribute constructor arguments.
ListBuffer<Type> argtypesBuf = new ListBuffer<>();
int pkind = attribArgs(tree.args, localEnv, argtypesBuf);
List<Type> argtypes = argtypesBuf.toList();
! List<Type> typeargtypes;
!
! // Attribute and annotate the type arguments
! ListBuffer<Type> typeargtypesbuf = new ListBuffer<>();
! int i = 0;
!
! for (List<JCExpression> l = tree.typeargs;
! l.nonEmpty(); l = l.tail, i++) {
! final JCExpression arg = l.head;
! annotate.enterStart();
! typeargtypesbuf.append(attribType(arg, localEnv));
! annotate.annotateTypeLater(arg, localEnv,
! localEnv.info.scope.owner,
! tree.pos(), currentLambda,
! annotate.constructorInvokeTypeArgCreator(i, tree.pos),
! speculative);
! annotate.flush();
! annotate.enterDone();
! }
! typeargtypes =
! chk.checkRefTypes(tree.typeargs, typeargtypesbuf.toList());
// If we have made no mistakes in the class type...
if (clazztype.hasTag(CLASS)) {
// Enums may not be instantiated except implicitly
if (allowEnums &&
*** 2188,2198 ****
try {
//create a 'fake' diamond AST node by removing type-argument trees
ta.arguments = List.nil();
ResultInfo findDiamondResult = new ResultInfo(VAL,
resultInfo.checkContext.inferenceContext().free(resultInfo.pt) ? Type.noType : pt());
! Type inferred = deferredAttr.attribSpeculative(tree, env, findDiamondResult).type;
Type polyPt = allowPoly ?
syms.objectType :
clazztype;
if (!inferred.isErroneous() &&
(allowPoly && pt() == Infer.anyPoly ?
--- 2358,2371 ----
try {
//create a 'fake' diamond AST node by removing type-argument trees
ta.arguments = List.nil();
ResultInfo findDiamondResult = new ResultInfo(VAL,
resultInfo.checkContext.inferenceContext().free(resultInfo.pt) ? Type.noType : pt());
! Type inferred = deferredAttr.attribSpeculative(tree, env,
! findDiamondResult,
! currentLambda,
! annotate.newObjCreator(tree.pos)).type;
Type polyPt = allowPoly ?
syms.objectType :
clazztype;
if (!inferred.isErroneous() &&
(allowPoly && pt() == Infer.anyPoly ?
*** 2250,2261 ****
--- 2423,2445 ----
public void visitNewArray(JCNewArray tree) {
Type owntype = types.createErrorType(tree.type);
Env<AttrContext> localEnv = env.dup(tree);
Type elemtype;
+
+ for(List<JCAnnotation> dim : tree.dimAnnotations) {
+ this.attribAnnotationTypes(dim, localEnv);
+ }
+
if (tree.elemtype != null) {
+ annotate.enterStart();
elemtype = attribType(tree.elemtype, localEnv);
+ annotate.annotateTypeLater(tree, env, env.info.scope.owner, tree.pos(),
+ currentLambda, annotate.newObjCreator(tree.pos),
+ speculative);
+ annotate.enterDone();
+ annotate.flush();
chk.validate(tree.elemtype, localEnv);
owntype = elemtype;
for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) {
attribExpr(l.head, localEnv, syms.intType);
owntype = new ArrayType(owntype, syms.arrayClass,
*** 2272,2281 ****
--- 2456,2466 ----
pt());
}
elemtype = types.createErrorType(pt());
}
}
+
if (tree.elems != null) {
attribExprs(tree.elems, localEnv, elemtype);
owntype = new ArrayType(elemtype, syms.arrayClass,
Type.noAnnotations);
}
*** 2310,2320 ****
localEnv.info.isSerializable = true;
}
List<Type> explicitParamTypes = null;
if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) {
//attribute lambda parameters
! attribStats(that.params, localEnv);
explicitParamTypes = TreeInfo.types(that.params);
}
Type lambdaType;
if (pt() != Type.recoveryType) {
--- 2495,2512 ----
localEnv.info.isSerializable = true;
}
List<Type> explicitParamTypes = null;
if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) {
//attribute lambda parameters
! int i = 0;
! Annotate.PositionCreator oldcreator = creator;
! for (List<JCVariableDecl> l = that.params;
! l.nonEmpty(); l = l.tail, i++) {
! creator = annotate.paramCreator(i);
! attribStat(l.head, that, localEnv);
! }
! creator = oldcreator;
explicitParamTypes = TreeInfo.types(that.params);
}
Type lambdaType;
if (pt() != Type.recoveryType) {
*** 2366,2376 ****
actuals.tail;
params = params.tail;
}
//attribute lambda parameters
! attribStats(that.params, localEnv);
if (arityMismatch) {
resultInfo.checkContext.report(that, diags.fragment("incompatible.arg.types.in.lambda"));
result = that.type = types.createErrorType(currentTarget);
return;
--- 2558,2568 ----
actuals.tail;
params = params.tail;
}
//attribute lambda parameters
! attribStats(that.params, that, localEnv);
if (arityMismatch) {
resultInfo.checkContext.report(that, diags.fragment("incompatible.arg.types.in.lambda"));
result = that.type = types.createErrorType(currentTarget);
return;
*** 2391,2404 ****
recoveryInfo :
new ResultInfo(VAL, lambdaType.getReturnType(), funcContext);
localEnv.info.returnResult = bodyResultInfo;
if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
! attribTree(that.getBody(), localEnv, bodyResultInfo);
} else {
JCBlock body = (JCBlock)that.body;
! attribStats(body.stats, localEnv);
}
result = check(that, currentTarget, VAL, resultInfo);
boolean isSpeculativeRound =
--- 2583,2596 ----
recoveryInfo :
new ResultInfo(VAL, lambdaType.getReturnType(), funcContext);
localEnv.info.returnResult = bodyResultInfo;
if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
! attribTree(that.getBody(), localEnv, that, bodyResultInfo);
} else {
JCBlock body = (JCBlock)that.body;
! attribStats(body.stats, that, localEnv);
}
result = check(that, currentTarget, VAL, resultInfo);
boolean isSpeculativeRound =
*** 2666,2688 ****
--- 2858,2890 ----
return lambdaEnv;
}
@Override
public void visitReference(final JCMemberReference that) {
+ final boolean isConstructor = that.getName() == names.init;
+
if (pt().isErroneous() || (pt().hasTag(NONE) && pt() != Type.recoveryType)) {
if (pt().hasTag(NONE)) {
//method reference only allowed in assignment or method invocation/cast context
log.error(that.pos(), "unexpected.mref");
}
result = that.type = types.createErrorType(pt());
return;
}
final Env<AttrContext> localEnv = env.dup(that);
try {
+ annotate.enterStart();
//attribute member reference qualifier - if this is a constructor
//reference, the expected kind must be a type
Type exprType = attribTree(that.expr, env, memberReferenceQualifierResult(that));
+ final Annotate.PositionCreator creator =
+ isConstructor ? annotate.constructorRefCreator(that.pos) :
+ annotate.methodRefCreator(that.pos);
+ annotate.annotateTypeLater(that.expr, localEnv, env.info.scope.owner, that.pos(),
+ currentLambda, creator, speculative);
+ annotate.enterDone();
+ annotate.flush();
if (that.getMode() == JCMemberReference.ReferenceMode.NEW) {
exprType = chk.checkConstructorRefType(that.expr, exprType);
if (!exprType.isErroneous() &&
exprType.isRaw() &&
*** 2708,2718 ****
--- 2910,2935 ----
}
//attrib type-arguments
List<Type> typeargtypes = List.nil();
if (that.typeargs != null) {
+ annotate.enterStart();
typeargtypes = attribTypes(that.typeargs, localEnv);
+
+ // Annotate type arguments
+ int i = 0;
+ for (List<JCExpression> l = that.typeargs;
+ l.nonEmpty(); l = l.tail, i++) {
+ final Annotate.PositionCreator typeArgCreator =
+ isConstructor ? annotate.constructorRefTypeArgCreator(i, that.pos) :
+ annotate.methodRefTypeArgCreator(i, that.pos);
+ final JCExpression arg = l.head;
+ annotate.annotateTypeLater(arg, env, env.info.scope.owner, that.pos(),
+ currentLambda, typeArgCreator, speculative);
+ }
+ annotate.flush();
+ annotate.enterDone();
}
Type desc;
Type currentTarget = pt();
boolean isTargetSerializable =
*** 3081,3091 ****
--- 3298,3315 ----
}
result = check(tree, owntype, VAL, resultInfo);
}
public void visitTypeCast(final JCTypeCast tree) {
+ annotate.enterStart();
Type clazztype = attribType(tree.clazz, env);
+ annotate.annotateTypeLater(tree.clazz, env, env.info.scope.owner,
+ tree.pos(), currentLambda,
+ annotate.castCreator(tree.pos),
+ speculative);
+ annotate.flush();
+ annotate.enterDone();
chk.validate(tree.clazz, env, false);
//a fresh environment is required for 292 inference to work properly ---
//see Infer.instantiatePolymorphicSignatureInstance()
Env<AttrContext> localEnv = env.dup(tree);
//should we propagate the target type?
*** 3114,3124 ****
--- 3338,3355 ----
}
public void visitTypeTest(JCInstanceOf tree) {
Type exprtype = chk.checkNullOrRefType(
tree.expr.pos(), attribExpr(tree.expr, env));
+ annotate.enterStart();
Type clazztype = attribType(tree.clazz, env);
+ annotate.annotateTypeLater(tree.clazz, env, env.info.scope.owner, tree.pos(),
+ currentLambda, annotate.instanceOfCreator(tree.pos),
+ speculative);
+ annotate.flush();
+ annotate.enterDone();
+
if (!clazztype.hasTag(TYPEVAR)) {
clazztype = chk.checkClassOrArrayType(tree.clazz.pos(), clazztype);
}
if (!clazztype.isErroneous() && !types.isReifiable(clazztype)) {
log.error(tree.clazz.pos(), "illegal.generic.type.for.instof");
*** 4074,4085 ****
public void visitAnnotation(JCAnnotation tree) {
Assert.error("should be handled in Annotate");
}
public void visitAnnotatedType(JCAnnotatedType tree) {
! Type underlyingType = attribType(tree.getUnderlyingType(), env);
this.attribAnnotationTypes(tree.annotations, env);
annotateType(tree, tree.annotations);
result = tree.type = underlyingType;
}
--- 4305,4321 ----
public void visitAnnotation(JCAnnotation tree) {
Assert.error("should be handled in Annotate");
}
+ /* This needs to be removed or otherwise changed, as it implicitly
+ * relies on the annotated types having previously been visited by
+ * Annotate.TypeAnnotate.
+ */
public void visitAnnotatedType(JCAnnotatedType tree) {
! Type underlyingType = attribTree(tree.getUnderlyingType(), env,
! resultInfo);
this.attribAnnotationTypes(tree.annotations, env);
annotateType(tree, tree.annotations);
result = tree.type = underlyingType;
}
*** 4094,4105 ****
--- 4330,4343 ----
}
@Override
public void run() {
List<Attribute.TypeCompound> compounds = fromAnnotations(annotations);
Assert.check(annotations.size() == compounds.size());
+ if (!tree.type.hasTag(TypeTag.PACKAGE)) {
tree.type = tree.type.annotatedType(compounds);
}
+ }
});
}
private static List<Attribute.TypeCompound> fromAnnotations(List<JCAnnotation> annotations) {
if (annotations.isEmpty()) {
*** 4346,4362 ****
isSerializable(c.type) &&
(c.flags() & Flags.ENUM) == 0 &&
checkForSerial(c)) {
checkSerialVersionUID(tree, c);
}
- if (allowTypeAnnos) {
- // Correctly organize the postions of the type annotations
- typeAnnotations.organizeTypeAnnotationsBodies(tree);
-
- // Check type annotations applicability rules
- validateTypeAnnotations(tree, false);
- }
}
// where
boolean checkForSerial(ClassSymbol c) {
if ((c.flags() & ABSTRACT) == 0) {
return true;
--- 4584,4593 ----
*** 4426,4435 ****
--- 4657,4671 ----
private Type capture(Type type) {
return types.capture(type);
}
+ /**************************************
+ * *
+ * This code is considered deprecated *
+ * *
+ **************************************/
public void validateTypeAnnotations(JCTree tree, boolean sigOnly) {
tree.accept(new TypeAnnotationsValidator(sigOnly));
}
//where
private final class TypeAnnotationsValidator extends TreeScanner {
*** 4476,4486 ****
scan(tree.defaultValue);
scan(tree.body);
}
}
public void visitVarDef(final JCVariableDecl tree) {
- //System.err.println("validateTypeAnnotations.visitVarDef " + tree);
if (tree.sym != null && tree.sym.type != null)
validateAnnotatedType(tree.vartype, tree.sym.type);
scan(tree.mods);
scan(tree.vartype);
if (!sigOnly) {
--- 4712,4721 ----
*** 4519,4529 ****
validateAnnotatedType(tree.elemtype, tree.elemtype.type);
}
super.visitNewArray(tree);
}
public void visitClassDef(JCClassDecl tree) {
- //System.err.println("validateTypeAnnotations.visitClassDef " + tree);
if (sigOnly) {
scan(tree.mods);
scan(tree.typarams);
scan(tree.extending);
scan(tree.implementing);
--- 4754,4763 ----
*** 4548,4558 ****
* of the symbol.
* Therefore, we need to override each individual location where a type
* can occur.
*/
private void validateAnnotatedType(final JCTree errtree, final Type type) {
- //System.err.println("Attr.validateAnnotatedType: " + errtree + " type: " + type);
if (type.isPrimitiveOrVoid()) {
return;
}
--- 4782,4791 ----
*** 4588,4604 ****
}
} else if (enclTr.hasTag(ANNOTATED_TYPE)) {
JCAnnotatedType at = (JCTree.JCAnnotatedType) enclTr;
if (enclTy == null || enclTy.hasTag(NONE)) {
if (at.getAnnotations().size() == 1) {
! log.error(at.underlyingType.pos(), "cant.type.annotate.scoping.1", at.getAnnotations().head.attribute);
} else {
ListBuffer<Attribute.Compound> comps = new ListBuffer<>();
for (JCAnnotation an : at.getAnnotations()) {
comps.add(an.attribute);
}
! log.error(at.underlyingType.pos(), "cant.type.annotate.scoping", comps.toList());
}
repeat = false;
}
enclTr = at.underlyingType;
// enclTy doesn't need to be changed
--- 4821,4837 ----
}
} else if (enclTr.hasTag(ANNOTATED_TYPE)) {
JCAnnotatedType at = (JCTree.JCAnnotatedType) enclTr;
if (enclTy == null || enclTy.hasTag(NONE)) {
if (at.getAnnotations().size() == 1) {
! //log.error(at.underlyingType.pos(), "cant.type.annotate.scoping.1", at.getAnnotations().head.attribute);
} else {
ListBuffer<Attribute.Compound> comps = new ListBuffer<>();
for (JCAnnotation an : at.getAnnotations()) {
comps.add(an.attribute);
}
! //log.error(at.underlyingType.pos(), "cant.type.annotate.scoping", comps.toList());
}
repeat = false;
}
enclTr = at.underlyingType;
// enclTy doesn't need to be changed
*** 4645,4654 ****
--- 4878,4889 ----
// Ensure that no declaration annotations are present.
// Note that a tree type might be an AnnotatedType with
// empty annotations, if only declaration annotations were given.
// This method will raise an error for such a type.
for (JCAnnotation ai : annotations) {
+ Assert.checkNonNull(ai.type);
+
if (!ai.type.isErroneous() &&
typeAnnotations.annotationType(ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) {
log.error(ai.pos(), "annotation.type.not.applicable");
}
}