1 package com.github.javaparser.ast.validator.chunks; 2 3 import com.github.javaparser.ast.Node; 4 import com.github.javaparser.ast.body.Parameter; 5 import com.github.javaparser.ast.body.VariableDeclarator; 6 import com.github.javaparser.ast.expr.ArrayCreationExpr; 7 import com.github.javaparser.ast.expr.LambdaExpr; 8 import com.github.javaparser.ast.expr.NullLiteralExpr; 9 import com.github.javaparser.ast.expr.VariableDeclarationExpr; 10 import com.github.javaparser.ast.stmt.ExpressionStmt; 11 import com.github.javaparser.ast.stmt.ForStmt; 12 import com.github.javaparser.ast.stmt.ForeachStmt; 13 import com.github.javaparser.ast.type.VarType; 14 import com.github.javaparser.ast.validator.ProblemReporter; 15 import com.github.javaparser.ast.validator.TypedValidator; 16 17 import java.util.Optional; 18 19 public class VarValidator implements TypedValidator<VarType> { 20 private boolean varAllowedInLambdaParameters; 21 22 public VarValidator(boolean varAllowedInLambdaParameters) { 23 this.varAllowedInLambdaParameters = varAllowedInLambdaParameters; 24 } 25 26 @Override 27 public void accept(VarType node, ProblemReporter reporter) { 28 // All allowed locations are within a VariableDeclaration inside a VariableDeclarationExpr inside something else. 29 Optional<VariableDeclarator> variableDeclarator = node.findParent(VariableDeclarator.class); 30 if (!variableDeclarator.isPresent()) { 31 // Java 11's var in lambda's 32 if (varAllowedInLambdaParameters) { 33 boolean valid = node 34 .findParent(Parameter.class) 35 .flatMap(Node::getParentNode) 36 .map((Node p) -> p instanceof LambdaExpr).orElse(false); 37 if (valid) { 38 return; 39 } 40 } 41 reportIllegalPosition(node, reporter); 42 return; 43 } 44 variableDeclarator.ifPresent(vd -> { 45 Optional<Node> variableDeclarationExpr = vd.getParentNode(); 46 if (!variableDeclarationExpr.isPresent()) { 47 reportIllegalPosition(node, reporter); 48 return; 49 } 50 variableDeclarationExpr.ifPresent(vdeNode -> { 51 if (!(vdeNode instanceof VariableDeclarationExpr)) { 52 reportIllegalPosition(node, reporter); 53 return; 54 } 55 VariableDeclarationExpr vde = (VariableDeclarationExpr) vdeNode; 56 if (vde.getVariables().size() > 1) { 57 reporter.report(vde, "\"var\" only takes a single variable."); 58 } 59 Optional<Node> container = vdeNode.getParentNode(); 60 if (!container.isPresent()) { 61 reportIllegalPosition(node, reporter); 62 return; 63 } 64 container.ifPresent(c -> { 65 boolean positionIsFine = c instanceof ForStmt || c instanceof ForeachStmt || c instanceof ExpressionStmt; 66 if (!positionIsFine) { 67 reportIllegalPosition(node, reporter); 68 } 69 // A local variable declaration ends up inside an ExpressionStmt. 70 if (c instanceof ExpressionStmt) { 71 if (!vd.getInitializer().isPresent()) { 72 reporter.report(node, "\"var\" needs an initializer."); 73 } 74 vd.getInitializer().ifPresent(initializer -> { 75 if (initializer instanceof NullLiteralExpr) { 76 reporter.report(node, "\"var\" cannot infer type from just null."); 77 } 78 if (initializer instanceof ArrayCreationExpr) { 79 reporter.report(node, "\"var\" cannot infer array types."); 80 } 81 }); 82 83 } 84 }); 85 }); 86 }); 87 88 } 89 90 private void reportIllegalPosition(VarType n, ProblemReporter reporter) { 91 reporter.report(n, "\"var\" is not allowed here."); 92 } 93 } 94