下面列出了com.sun.source.tree.LambdaExpressionTree.BodyKind#EXPRESSION 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Hint(displayName="#DN_expression2Return", description="#DESC_expression2Return", category="suggestions", hintKind=Hint.Kind.ACTION,
minSourceVersion = "8")
@Messages({
"DN_expression2Return=Convert Lambda Body to Use a Block",
"DESC_expression2Return=Converts lambda bodies to use blocks rather than expressions",
"ERR_expression2Return=",
"FIX_expression2Return=Use block as the lambda's body"
})
@TriggerPattern("($args$) -> $lambdaExpression")
public static ErrorDescription expression2Return(HintContext ctx) {
if (((LambdaExpressionTree) ctx.getPath().getLeaf()).getBodyKind() != BodyKind.EXPRESSION) {
return null;
}
TypeMirror lambdaExpressionType = ctx.getInfo().getTrees().getTypeMirror(ctx.getVariables().get("$lambdaExpression"));
String target = lambdaExpressionType == null || lambdaExpressionType.getKind() != TypeKind.VOID
? "($args$) -> { return $lambdaExpression; }"
: "($args$) -> { $lambdaExpression; }";
return ErrorDescriptionFactory.forTree(ctx, ctx.getPath(), Bundle.ERR_expression2Return(), JavaFixUtilities.rewriteFix(ctx, Bundle.FIX_expression2Return(), ctx.getPath(), target));
}
/** Check lambda against given target result */
private void checkLambdaCompatible(Type descriptor, ResultInfo resultInfo) {
CheckContext checkContext = resultInfo.checkContext;
ResultInfo bodyResultInfo = attr.lambdaBodyResult(speculativeTree, descriptor, resultInfo);
for (JCReturn ret : returnExpressions()) {
Type t = getReturnType(ret);
if (speculativeTree.getBodyKind() == BodyKind.EXPRESSION || !t.hasTag(VOID)) {
checkSpeculative(ret.expr, t, bodyResultInfo);
}
}
attr.checkLambdaCompatible(speculativeTree, descriptor, checkContext);
}
@Override
public void visitLambda(JCLambda tree) {
if (inLambda || tree.getBodyKind() == BodyKind.EXPRESSION) {
return;
}
inLambda = true;
try {
super.visitLambda(tree);
} finally {
inLambda = false;
}
}
boolean isSimpleStringArg(JCExpression e) {
switch (e.getTag()) {
case LAMBDA:
JCLambda lambda = (JCLambda)e;
return (lambda.getBodyKind() == BodyKind.EXPRESSION) &&
isSimpleStringArg((JCExpression)lambda.body);
default:
Symbol argSym = TreeInfo.symbolFor(e);
return (e.type.constValue() != null ||
(argSym != null && argSym.kind == Kinds.Kind.VAR));
}
}
/** Check lambda against given target result */
private void checkLambdaCompatible(Type descriptor, ResultInfo resultInfo) {
CheckContext checkContext = resultInfo.checkContext;
ResultInfo bodyResultInfo = attr.lambdaBodyResult(speculativeTree, descriptor, resultInfo);
for (JCReturn ret : returnExpressions()) {
Type t = getReturnType(ret);
if (speculativeTree.getBodyKind() == BodyKind.EXPRESSION || !t.hasTag(VOID)) {
checkSpeculative(ret.expr, t, bodyResultInfo);
}
}
attr.checkLambdaCompatible(speculativeTree, descriptor, checkContext);
}
@Override
public void visitLambda(JCLambda tree) {
if (inLambda || tree.getBodyKind() == BodyKind.EXPRESSION) {
return;
}
inLambda = true;
try {
super.visitLambda(tree);
} finally {
inLambda = false;
}
}
@Override
public BodyKind getBodyKind() {
return body.hasTag(BLOCK) ?
BodyKind.STATEMENT :
BodyKind.EXPRESSION;
}
@Override
public void visitLambda(JCLambda tree) {
Check.CheckContext checkContext = resultInfo.checkContext;
Type pt = resultInfo.pt;
if (!inferenceContext.inferencevars.contains(pt)) {
//must be a functional descriptor
Type descriptorType = null;
try {
descriptorType = types.findDescriptorType(pt);
} catch (Types.FunctionDescriptorLookupError ex) {
checkContext.report(null, ex.getDiagnostic());
}
if (descriptorType.getParameterTypes().length() != tree.params.length()) {
checkContext.report(tree,
diags.fragment("incompatible.arg.types.in.lambda"));
}
Type currentReturnType = descriptorType.getReturnType();
boolean returnTypeIsVoid = currentReturnType.hasTag(VOID);
if (tree.getBodyKind() == BodyKind.EXPRESSION) {
boolean isExpressionCompatible = !returnTypeIsVoid ||
TreeInfo.isExpressionStatement((JCExpression)tree.getBody());
if (!isExpressionCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment("incompatible.ret.type.in.lambda",
diags.fragment("missing.ret.val", currentReturnType)));
}
} else {
LambdaBodyStructChecker lambdaBodyChecker =
new LambdaBodyStructChecker();
tree.body.accept(lambdaBodyChecker);
boolean isVoidCompatible = lambdaBodyChecker.isVoidCompatible;
if (returnTypeIsVoid) {
if (!isVoidCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment("unexpected.ret.val"));
}
} else {
boolean isValueCompatible = lambdaBodyChecker.isPotentiallyValueCompatible
&& !canLambdaBodyCompleteNormally(tree);
if (!isValueCompatible && !isVoidCompatible) {
log.error(tree.body.pos(),
"lambda.body.neither.value.nor.void.compatible");
}
if (!isValueCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment("incompatible.ret.type.in.lambda",
diags.fragment("missing.ret.val", currentReturnType)));
}
}
}
}
}
@Override
public BodyKind getBodyKind() {
return body.hasTag(BLOCK) ?
BodyKind.STATEMENT :
BodyKind.EXPRESSION;
}
@Override
public void visitLambda(JCLambda tree) {
Check.CheckContext checkContext = resultInfo.checkContext;
Type pt = resultInfo.pt;
if (!inferenceContext.inferencevars.contains(pt)) {
//must be a functional descriptor
Type descriptorType = null;
try {
descriptorType = types.findDescriptorType(pt);
} catch (Types.FunctionDescriptorLookupError ex) {
checkContext.report(null, ex.getDiagnostic());
}
if (descriptorType.getParameterTypes().length() != tree.params.length()) {
checkContext.report(tree,
diags.fragment("incompatible.arg.types.in.lambda"));
}
Type currentReturnType = descriptorType.getReturnType();
boolean returnTypeIsVoid = currentReturnType.hasTag(VOID);
if (tree.getBodyKind() == BodyKind.EXPRESSION) {
boolean isExpressionCompatible = !returnTypeIsVoid ||
TreeInfo.isExpressionStatement((JCExpression)tree.getBody());
if (!isExpressionCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment("incompatible.ret.type.in.lambda",
diags.fragment("missing.ret.val", currentReturnType)));
}
} else {
LambdaBodyStructChecker lambdaBodyChecker =
new LambdaBodyStructChecker();
tree.body.accept(lambdaBodyChecker);
boolean isVoidCompatible = lambdaBodyChecker.isVoidCompatible;
if (returnTypeIsVoid) {
if (!isVoidCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment("unexpected.ret.val"));
}
} else {
boolean isValueCompatible = lambdaBodyChecker.isPotentiallyValueCompatible
&& !canLambdaBodyCompleteNormally(tree);
if (!isValueCompatible && !isVoidCompatible) {
log.error(tree.body.pos(),
"lambda.body.neither.value.nor.void.compatible");
}
if (!isValueCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment("incompatible.ret.type.in.lambda",
diags.fragment("missing.ret.val", currentReturnType)));
}
}
}
}
}
@Override
public BodyKind getBodyKind() {
return body.hasTag(BLOCK) ?
BodyKind.STATEMENT :
BodyKind.EXPRESSION;
}
@Override
public void visitLambda(JCLambda tree) {
Check.CheckContext checkContext = resultInfo.checkContext;
Type pt = resultInfo.pt;
if (!inferenceContext.inferencevars.contains(pt)) {
//must be a functional descriptor
Type descriptorType = null;
try {
descriptorType = types.findDescriptorType(pt);
} catch (Types.FunctionDescriptorLookupError ex) {
checkContext.report(null, ex.getDiagnostic());
}
if (descriptorType.getParameterTypes().length() != tree.params.length()) {
checkContext.report(tree,
diags.fragment("incompatible.arg.types.in.lambda"));
}
Type currentReturnType = descriptorType.getReturnType();
boolean returnTypeIsVoid = currentReturnType.hasTag(VOID);
if (tree.getBodyKind() == BodyKind.EXPRESSION) {
boolean isExpressionCompatible = !returnTypeIsVoid ||
TreeInfo.isExpressionStatement((JCExpression)tree.getBody());
if (!isExpressionCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment("incompatible.ret.type.in.lambda",
diags.fragment("missing.ret.val", currentReturnType)));
}
} else {
LambdaBodyStructChecker lambdaBodyChecker =
new LambdaBodyStructChecker();
tree.body.accept(lambdaBodyChecker);
boolean isVoidCompatible = lambdaBodyChecker.isVoidCompatible;
if (returnTypeIsVoid) {
if (!isVoidCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment("unexpected.ret.val"));
}
} else {
boolean isValueCompatible = lambdaBodyChecker.isPotentiallyValueCompatible
&& !canLambdaBodyCompleteNormally(tree);
if (!isValueCompatible && !isVoidCompatible) {
log.error(tree.body.pos(),
"lambda.body.neither.value.nor.void.compatible");
}
if (!isValueCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment("incompatible.ret.type.in.lambda",
diags.fragment("missing.ret.val", currentReturnType)));
}
}
}
}
}
@Override
public void visitLambda(JCLambda tree) {
Check.CheckContext checkContext = resultInfo.checkContext;
Type pt = resultInfo.pt;
if (!inferenceContext.inferencevars.contains(pt)) {
//must be a functional descriptor
Type descriptorType = null;
try {
descriptorType = types.findDescriptorType(pt);
} catch (Types.FunctionDescriptorLookupError ex) {
checkContext.report(null, ex.getDiagnostic());
}
if (descriptorType.getParameterTypes().length() != tree.params.length()) {
checkContext.report(tree,
diags.fragment(Fragments.IncompatibleArgTypesInLambda));
}
Type currentReturnType = descriptorType.getReturnType();
boolean returnTypeIsVoid = currentReturnType.hasTag(VOID);
if (tree.getBodyKind() == BodyKind.EXPRESSION) {
boolean isExpressionCompatible = !returnTypeIsVoid ||
TreeInfo.isExpressionStatement((JCExpression)tree.getBody());
if (!isExpressionCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment(Fragments.IncompatibleRetTypeInLambda(Fragments.MissingRetVal(currentReturnType))));
}
} else {
LambdaBodyStructChecker lambdaBodyChecker =
new LambdaBodyStructChecker();
tree.body.accept(lambdaBodyChecker);
boolean isVoidCompatible = lambdaBodyChecker.isVoidCompatible;
if (returnTypeIsVoid) {
if (!isVoidCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment(Fragments.UnexpectedRetVal));
}
} else {
boolean isValueCompatible = lambdaBodyChecker.isPotentiallyValueCompatible
&& !canLambdaBodyCompleteNormally(tree);
if (!isValueCompatible && !isVoidCompatible) {
log.error(tree.body.pos(),
Errors.LambdaBodyNeitherValueNorVoidCompatible);
}
if (!isValueCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment(Fragments.IncompatibleRetTypeInLambda(Fragments.MissingRetVal(currentReturnType))));
}
}
}
}
}
@Override
public BodyKind getBodyKind() {
return body.hasTag(BLOCK) ?
BodyKind.STATEMENT :
BodyKind.EXPRESSION;
}
@Override
public void visitLambda(JCLambda tree) {
Check.CheckContext checkContext = resultInfo.checkContext;
Type pt = resultInfo.pt;
if (!inferenceContext.inferencevars.contains(pt)) {
//must be a functional descriptor
Type descriptorType = null;
try {
descriptorType = types.findDescriptorType(pt);
} catch (Types.FunctionDescriptorLookupError ex) {
checkContext.report(null, ex.getDiagnostic());
}
if (descriptorType.getParameterTypes().length() != tree.params.length()) {
checkContext.report(tree,
diags.fragment("incompatible.arg.types.in.lambda"));
}
Type currentReturnType = descriptorType.getReturnType();
boolean returnTypeIsVoid = currentReturnType.hasTag(VOID);
if (tree.getBodyKind() == BodyKind.EXPRESSION) {
boolean isExpressionCompatible = !returnTypeIsVoid ||
TreeInfo.isExpressionStatement((JCExpression)tree.getBody());
if (!isExpressionCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment("incompatible.ret.type.in.lambda",
diags.fragment("missing.ret.val", currentReturnType)));
}
} else {
LambdaBodyStructChecker lambdaBodyChecker =
new LambdaBodyStructChecker();
tree.body.accept(lambdaBodyChecker);
boolean isVoidCompatible = lambdaBodyChecker.isVoidCompatible;
if (returnTypeIsVoid) {
if (!isVoidCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment("unexpected.ret.val"));
}
} else {
boolean isValueCompatible = lambdaBodyChecker.isPotentiallyValueCompatible
&& !canLambdaBodyCompleteNormally(tree);
if (!isValueCompatible && !isVoidCompatible) {
log.error(tree.body.pos(),
"lambda.body.neither.value.nor.void.compatible");
}
if (!isValueCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment("incompatible.ret.type.in.lambda",
diags.fragment("missing.ret.val", currentReturnType)));
}
}
}
}
}
@Override
public void visitLambda(JCLambda tree) {
Check.CheckContext checkContext = resultInfo.checkContext;
Type pt = resultInfo.pt;
if (!inferenceContext.inferencevars.contains(pt)) {
//must be a functional descriptor
Type descriptorType = null;
try {
descriptorType = types.findDescriptorType(pt);
} catch (Types.FunctionDescriptorLookupError ex) {
checkContext.report(null, ex.getDiagnostic());
}
if (descriptorType.getParameterTypes().length() != tree.params.length()) {
checkContext.report(tree,
diags.fragment("incompatible.arg.types.in.lambda"));
}
Type currentReturnType = descriptorType.getReturnType();
boolean returnTypeIsVoid = currentReturnType.hasTag(VOID);
if (tree.getBodyKind() == BodyKind.EXPRESSION) {
boolean isExpressionCompatible = !returnTypeIsVoid ||
TreeInfo.isExpressionStatement((JCExpression)tree.getBody());
if (!isExpressionCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment("incompatible.ret.type.in.lambda",
diags.fragment("missing.ret.val", currentReturnType)));
}
} else {
LambdaBodyStructChecker lambdaBodyChecker =
new LambdaBodyStructChecker();
tree.body.accept(lambdaBodyChecker);
boolean isVoidCompatible = lambdaBodyChecker.isVoidCompatible;
if (returnTypeIsVoid) {
if (!isVoidCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment("unexpected.ret.val"));
}
} else {
boolean isValueCompatible = lambdaBodyChecker.isPotentiallyValueCompatible
&& !canLambdaBodyCompleteNormally(tree);
if (!isValueCompatible && !isVoidCompatible) {
log.error(tree.body.pos(),
"lambda.body.neither.value.nor.void.compatible");
}
if (!isValueCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment("incompatible.ret.type.in.lambda",
diags.fragment("missing.ret.val", currentReturnType)));
}
}
}
}
}
@Override
public BodyKind getBodyKind() {
return body.hasTag(BLOCK) ?
BodyKind.STATEMENT :
BodyKind.EXPRESSION;
}
@Override
public void visitLambda(JCLambda tree) {
Check.CheckContext checkContext = resultInfo.checkContext;
Type pt = resultInfo.pt;
if (!inferenceContext.inferencevars.contains(pt)) {
//must be a functional descriptor
Type descriptorType = null;
try {
descriptorType = types.findDescriptorType(pt);
} catch (Types.FunctionDescriptorLookupError ex) {
checkContext.report(null, ex.getDiagnostic());
}
if (descriptorType.getParameterTypes().length() != tree.params.length()) {
checkContext.report(tree,
diags.fragment("incompatible.arg.types.in.lambda"));
}
Type currentReturnType = descriptorType.getReturnType();
boolean returnTypeIsVoid = currentReturnType.hasTag(VOID);
if (tree.getBodyKind() == BodyKind.EXPRESSION) {
boolean isExpressionCompatible = !returnTypeIsVoid ||
TreeInfo.isExpressionStatement((JCExpression)tree.getBody());
if (!isExpressionCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment("incompatible.ret.type.in.lambda",
diags.fragment("missing.ret.val", currentReturnType)));
}
} else {
LambdaBodyStructChecker lambdaBodyChecker =
new LambdaBodyStructChecker();
tree.body.accept(lambdaBodyChecker);
boolean isVoidCompatible = lambdaBodyChecker.isVoidCompatible;
if (returnTypeIsVoid) {
if (!isVoidCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment("unexpected.ret.val"));
}
} else {
boolean isValueCompatible = lambdaBodyChecker.isPotentiallyValueCompatible
&& !canLambdaBodyCompleteNormally(tree);
if (!isValueCompatible && !isVoidCompatible) {
log.error(tree.body.pos(),
"lambda.body.neither.value.nor.void.compatible");
}
if (!isValueCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment("incompatible.ret.type.in.lambda",
diags.fragment("missing.ret.val", currentReturnType)));
}
}
}
}
}
@Override
public BodyKind getBodyKind() {
return body.hasTag(BLOCK) ?
BodyKind.STATEMENT :
BodyKind.EXPRESSION;
}
@Override
public BodyKind getBodyKind() {
return body.hasTag(BLOCK) ?
BodyKind.STATEMENT :
BodyKind.EXPRESSION;
}