8076279: Refactor Attr.check* methods to receive/handle a CheckMode enumeration

Internal cleanup to Attr.check to make use of a new abstraction CheckMode

Reviewed-by: mcimadamore
This commit is contained in:
Srikanth Adayapalam 2015-04-28 15:20:25 +05:30
parent e57ef90dd9
commit 0b27399a55

View File

@ -165,8 +165,6 @@ public class Attr extends JCTree.Visitor {
unknownTypeInfo = new ResultInfo(KindSelector.TYP, Type.noType); unknownTypeInfo = new ResultInfo(KindSelector.TYP, Type.noType);
unknownTypeExprInfo = new ResultInfo(KindSelector.VAL_TYP, Type.noType); unknownTypeExprInfo = new ResultInfo(KindSelector.VAL_TYP, Type.noType);
recoveryInfo = new RecoveryInfo(deferredAttr.emptyDeferredAttrContext); recoveryInfo = new RecoveryInfo(deferredAttr.emptyDeferredAttrContext);
noCheckTree = make.at(-1).Skip();
} }
/** Switch: relax some constraints for retrofit mode. /** Switch: relax some constraints for retrofit mode.
@ -225,26 +223,6 @@ public class Attr extends JCTree.Visitor {
final Type found, final Type found,
final KindSelector ownkind, final KindSelector ownkind,
final ResultInfo resultInfo) { final ResultInfo resultInfo) {
return check(tree, found, ownkind, resultInfo, true);
}
/** 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
* are correct.
*
* @param tree The tree whose kind and type is checked
* @param found The computed type of the tree
* @param ownkind The computed kind of the tree
* @param resultInfo The expected result of the tree
* @param recheckPostInference If true and inference is underway, arrange to recheck the tree after inference finishes.
*/
Type check(final JCTree tree,
final Type found,
final KindSelector ownkind,
final ResultInfo resultInfo,
boolean recheckPostInference) {
InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext(); InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
Type owntype; Type owntype;
boolean shouldCheck = !found.hasTag(ERROR) && boolean shouldCheck = !found.hasTag(ERROR) &&
@ -259,12 +237,12 @@ public class Attr extends JCTree.Visitor {
//delay the check if there are inference variables in the found type //delay the check if there are inference variables in the found type
//this means we are dealing with a partially inferred poly expression //this means we are dealing with a partially inferred poly expression
owntype = shouldCheck ? resultInfo.pt : found; owntype = shouldCheck ? resultInfo.pt : found;
if (recheckPostInference) { if (resultInfo.checkMode.installPostInferenceHook()) {
inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt), inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt),
instantiatedContext -> { instantiatedContext -> {
ResultInfo pendingResult = ResultInfo pendingResult =
resultInfo.dup(inferenceContext.asInstType(resultInfo.pt)); resultInfo.dup(inferenceContext.asInstType(resultInfo.pt));
check(tree, inferenceContext.asInstType(found), ownkind, pendingResult, false); check(tree, inferenceContext.asInstType(found), ownkind, pendingResult);
}); });
} }
} else { } else {
@ -272,7 +250,7 @@ public class Attr extends JCTree.Visitor {
resultInfo.check(tree, found) : resultInfo.check(tree, found) :
found; found;
} }
if (tree != noCheckTree) { if (resultInfo.checkMode.updateTreeType()) {
tree.type = owntype; tree.type = owntype;
} }
return owntype; return owntype;
@ -455,20 +433,60 @@ public class Attr extends JCTree.Visitor {
} }
} }
/**
* Mode controlling behavior of Attr.Check
*/
enum CheckMode {
NORMAL,
NO_TREE_UPDATE { // Mode signalling 'fake check' - skip tree update
@Override
public boolean updateTreeType() {
return false;
}
},
NO_INFERENCE_HOOK { // Mode signalling that caller will manage free types in tree decorations.
@Override
public boolean installPostInferenceHook() {
return false;
}
};
public boolean updateTreeType() {
return true;
}
public boolean installPostInferenceHook() {
return true;
}
}
class ResultInfo { class ResultInfo {
final KindSelector pkind; final KindSelector pkind;
final Type pt; final Type pt;
final CheckContext checkContext; final CheckContext checkContext;
final CheckMode checkMode;
ResultInfo(KindSelector pkind, Type pt) { ResultInfo(KindSelector pkind, Type pt) {
this(pkind, pt, chk.basicHandler); this(pkind, pt, chk.basicHandler, CheckMode.NORMAL);
}
ResultInfo(KindSelector pkind, Type pt, CheckMode checkMode) {
this(pkind, pt, chk.basicHandler, checkMode);
} }
protected ResultInfo(KindSelector pkind, protected ResultInfo(KindSelector pkind,
Type pt, CheckContext checkContext) { Type pt, CheckContext checkContext) {
this(pkind, pt, checkContext, CheckMode.NORMAL);
}
protected ResultInfo(KindSelector pkind,
Type pt, CheckContext checkContext, CheckMode checkMode) {
this.pkind = pkind; this.pkind = pkind;
this.pt = pt; this.pt = pt;
this.checkContext = checkContext; this.checkContext = checkContext;
this.checkMode = checkMode;
} }
protected Type check(final DiagnosticPosition pos, final Type found) { protected Type check(final DiagnosticPosition pos, final Type found) {
@ -476,15 +494,23 @@ public class Attr extends JCTree.Visitor {
} }
protected ResultInfo dup(Type newPt) { protected ResultInfo dup(Type newPt) {
return new ResultInfo(pkind, newPt, checkContext); return new ResultInfo(pkind, newPt, checkContext, checkMode);
} }
protected ResultInfo dup(CheckContext newContext) { protected ResultInfo dup(CheckContext newContext) {
return new ResultInfo(pkind, pt, newContext); return new ResultInfo(pkind, pt, newContext, checkMode);
} }
protected ResultInfo dup(Type newPt, CheckContext newContext) { protected ResultInfo dup(Type newPt, CheckContext newContext) {
return new ResultInfo(pkind, newPt, newContext); return new ResultInfo(pkind, newPt, newContext, checkMode);
}
protected ResultInfo dup(Type newPt, CheckContext newContext, CheckMode newMode) {
return new ResultInfo(pkind, newPt, newContext, newMode);
}
protected ResultInfo dup(CheckMode newMode) {
return new ResultInfo(pkind, pt, checkContext, newMode);
} }
@Override @Override
@ -550,10 +576,6 @@ public class Attr extends JCTree.Visitor {
*/ */
Type result; Type result;
/** Synthetic tree to be used during 'fake' checks.
*/
JCTree noCheckTree;
/** Visitor method: attribute a tree, catching any completion failure /** Visitor method: attribute a tree, catching any completion failure
* exceptions. Return the tree's type. * exceptions. Return the tree's type.
* *
@ -2055,9 +2077,9 @@ public class Attr extends JCTree.Visitor {
enclosingContext.report(tree.clazz, enclosingContext.report(tree.clazz,
diags.fragment("cant.apply.diamond.1", diags.fragment("diamond", csym), details)); diags.fragment("cant.apply.diamond.1", diags.fragment("diamond", csym), details));
} }
}); }, CheckMode.NO_TREE_UPDATE);
Type constructorType = tree.constructorType = types.createErrorType(clazztype); Type constructorType = tree.constructorType = types.createErrorType(clazztype);
constructorType = checkId(noCheckTree, site, constructorType = checkId(tree, site,
constructor, constructor,
diamondEnv, diamondEnv,
diamondResult); diamondResult);
@ -2083,11 +2105,11 @@ public class Attr extends JCTree.Visitor {
tree.constructor = rs.resolveConstructor( tree.constructor = rs.resolveConstructor(
tree.pos(), rsEnv, clazztype, argtypes, typeargtypes); tree.pos(), rsEnv, clazztype, argtypes, typeargtypes);
if (cdef == null) { //do not check twice! if (cdef == null) { //do not check twice!
tree.constructorType = checkId(noCheckTree, tree.constructorType = checkId(tree,
clazztype, clazztype,
tree.constructor, tree.constructor,
rsEnv, rsEnv,
new ResultInfo(pkind, newMethodTemplate(syms.voidType, argtypes, typeargtypes))); new ResultInfo(pkind, newMethodTemplate(syms.voidType, argtypes, typeargtypes), CheckMode.NO_TREE_UPDATE));
if (rsEnv.info.lastResolveVarargs()) if (rsEnv.info.lastResolveVarargs())
Assert.check(tree.constructorType.isErroneous() || tree.varargsElement != null); Assert.check(tree.constructorType.isErroneous() || tree.varargsElement != null);
} }
@ -2220,15 +2242,15 @@ public class Attr extends JCTree.Visitor {
tree.pos(), localEnv, clazztype, finalargtypes, typeargtypes); tree.pos(), localEnv, clazztype, finalargtypes, typeargtypes);
Assert.check(!sym.kind.isResolutionError()); Assert.check(!sym.kind.isResolutionError());
tree.constructor = sym; tree.constructor = sym;
tree.constructorType = checkId(noCheckTree, tree.constructorType = checkId(tree,
clazztype, clazztype,
tree.constructor, tree.constructor,
localEnv, localEnv,
new ResultInfo(pkind, newMethodTemplate(syms.voidType, finalargtypes, typeargtypes))); new ResultInfo(pkind, newMethodTemplate(syms.voidType, finalargtypes, typeargtypes), CheckMode.NO_TREE_UPDATE));
} }
Type owntype = (tree.constructor != null && tree.constructor.kind == MTH) ? Type owntype = (tree.constructor != null && tree.constructor.kind == MTH) ?
clazztype : types.createErrorType(tree.type); clazztype : types.createErrorType(tree.type);
result = check(tree, owntype, KindSelector.VAL, resultInfo, false); result = check(tree, owntype, KindSelector.VAL, resultInfo.dup(CheckMode.NO_INFERENCE_HOOK));
chk.validate(tree.typeargs, localEnv); chk.validate(tree.typeargs, localEnv);
} }
@ -2840,9 +2862,9 @@ public class Attr extends JCTree.Visitor {
resultInfo.dup(newMethodTemplate( resultInfo.dup(newMethodTemplate(
desc.getReturnType().hasTag(VOID) ? Type.noType : desc.getReturnType(), desc.getReturnType().hasTag(VOID) ? Type.noType : desc.getReturnType(),
that.kind.isUnbound() ? argtypes.tail : argtypes, typeargtypes), that.kind.isUnbound() ? argtypes.tail : argtypes, typeargtypes),
new FunctionalReturnContext(resultInfo.checkContext)); new FunctionalReturnContext(resultInfo.checkContext), CheckMode.NO_TREE_UPDATE);
Type refType = checkId(noCheckTree, lookupHelper.site, refSym, localEnv, checkInfo); Type refType = checkId(that, lookupHelper.site, refSym, localEnv, checkInfo);
if (that.kind.isUnbound() && if (that.kind.isUnbound() &&
resultInfo.checkContext.inferenceContext().free(argtypes.head)) { resultInfo.checkContext.inferenceContext().free(argtypes.head)) {
@ -3996,8 +4018,8 @@ public class Attr extends JCTree.Visitor {
all_multicatchTypes.append(ctype); all_multicatchTypes.append(ctype);
} }
} }
Type t = check(noCheckTree, types.lub(multicatchTypes.toList()), Type t = check(tree, types.lub(multicatchTypes.toList()),
KindSelector.TYP, resultInfo); KindSelector.TYP, resultInfo.dup(CheckMode.NO_TREE_UPDATE));
if (t.hasTag(CLASS)) { if (t.hasTag(CLASS)) {
List<Type> alternatives = List<Type> alternatives =
((all_multicatchTypes == null) ? multicatchTypes : all_multicatchTypes).toList(); ((all_multicatchTypes == null) ? multicatchTypes : all_multicatchTypes).toList();