--- a/langtools/make/tools/crules/AssertCheckAnalyzer.java Mon Mar 02 10:41:08 2015 +0530
+++ b/langtools/make/tools/crules/AssertCheckAnalyzer.java Thu Mar 05 13:10:49 2015 +0000
@@ -23,10 +23,14 @@
package crules;
+import com.sun.source.tree.LambdaExpressionTree.BodyKind;
import com.sun.source.util.JavacTask;
import com.sun.source.util.TaskEvent.Kind;
+import com.sun.tools.javac.code.Kinds;
import com.sun.tools.javac.code.Symbol;
+import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.tree.JCTree.JCExpression;
+import com.sun.tools.javac.tree.JCTree.JCLambda;
import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
import com.sun.tools.javac.tree.JCTree.Tag;
import com.sun.tools.javac.tree.TreeInfo;
@@ -35,6 +39,22 @@
public class AssertCheckAnalyzer extends AbstractCodingRulesAnalyzer {
+ enum AssertOverloadKind {
+ EAGER("crules.should.not.use.eager.string.evaluation"),
+ LAZY("crules.should.not.use.lazy.string.evaluation"),
+ NONE(null);
+
+ String errKey;
+
+ AssertOverloadKind(String errKey) {
+ this.errKey = errKey;
+ }
+
+ boolean simpleArgExpected() {
+ return this == AssertOverloadKind.EAGER;
+ }
+ }
+
public AssertCheckAnalyzer(JavacTask task) {
super(task);
treeVisitor = new AssertCheckVisitor();
@@ -45,20 +65,46 @@
@Override
public void visitApply(JCMethodInvocation tree) {
- Symbol method = TreeInfo.symbolFor(tree);
- if (method != null &&
- method.owner.getQualifiedName().contentEquals(Assert.class.getName()) &&
- !method.name.contentEquals("error")) {
+ Symbol m = TreeInfo.symbolFor(tree);
+ AssertOverloadKind ak = assertOverloadKind(m);
+ if (ak != AssertOverloadKind.NONE &&
+ !m.name.contentEquals("error")) {
JCExpression lastParam = tree.args.last();
- if (lastParam != null &&
- lastParam.type.tsym == syms.stringType.tsym &&
- lastParam.hasTag(Tag.PLUS)) {
- messages.error(tree, "crules.should.not.use.string.concatenation");
+ if (isSimpleStringArg(lastParam) != ak.simpleArgExpected()) {
+ messages.error(lastParam, ak.errKey);
}
}
super.visitApply(tree);
}
+ AssertOverloadKind assertOverloadKind(Symbol method) {
+ if (method == null ||
+ !method.owner.getQualifiedName().contentEquals(Assert.class.getName()) ||
+ method.type.getParameterTypes().tail == null) {
+ return AssertOverloadKind.NONE;
+ }
+ Type formal = method.type.getParameterTypes().last();
+ if (types.isSameType(formal, syms.stringType)) {
+ return AssertOverloadKind.EAGER;
+ } else if (types.isSameType(types.erasure(formal), types.erasure(syms.supplierType))) {
+ return AssertOverloadKind.LAZY;
+ } else {
+ return AssertOverloadKind.NONE;
+ }
+ }
+
+ 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));
+ }
+ }
}
}