package lombok.eclipse.handlers;
import static lombok.core.handlers.HandlerUtil.handleFlagUsage;
import static lombok.eclipse.handlers.EclipseHandlerUtil.typeMatches;
import lombok.ConfigurationKeys;
import lombok.val;
import lombok.var;
import lombok.core.HandlerPriority;
import lombok.eclipse.DeferUntilPostDiet;
import lombok.eclipse.EclipseASTAdapter;
import lombok.eclipse.EclipseASTVisitor;
import lombok.eclipse.EclipseNode;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
import org.eclipse.jdt.internal.compiler.ast.ForStatement;
import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.mangosdk.spi.ProviderFor;
@ProviderFor(EclipseASTVisitor.class)
@DeferUntilPostDiet
@HandlerPriority(65536)
public class HandleVal extends EclipseASTAdapter {
@Override public void visitLocal(EclipseNode localNode, LocalDeclaration local) {
TypeReference type = local.type;
boolean isVal = typeMatches(val.class, localNode, type);
boolean isVar = typeMatches(var.class, localNode, type);
if (!(isVal || isVar)) return;
if (isVal) handleFlagUsage(localNode, ConfigurationKeys.VAL_FLAG_USAGE, "val");
if (isVar) handleFlagUsage(localNode, ConfigurationKeys.VAR_FLAG_USAGE, "var");
boolean variableOfForEach = false;
if (localNode.directUp().get() instanceof ForeachStatement) {
ForeachStatement fs = (ForeachStatement) localNode.directUp().get();
variableOfForEach = fs.elementVariable == local;
}
String annotation = isVal ? "val" : "var";
if (local.initialization == null && !variableOfForEach) {
localNode.addError("'" + annotation + "' on a local variable requires an initializer expression");
return;
}
if (local.initialization instanceof ArrayInitializer) {
localNode.addError("'" + annotation + "' is not compatible with array initializer expressions. Use the full form (new int[] { ... } instead of just { ... })");
return;
}
ASTNode parentRaw = localNode.directUp().get();
if (isVal && parentRaw instanceof ForStatement) {
localNode.addError("'val' is not allowed in old-style for loops");
return;
}
if (parentRaw instanceof ForStatement && ((ForStatement) parentRaw).initializations != null && ((ForStatement) parentRaw).initializations.length > 1) {
localNode.addError("'var' is not allowed in old-style for loops if there is more than 1 initializer");
return;
}
if (local.initialization != null && local.initialization.getClass().getName().equals("org.eclipse.jdt.internal.compiler.ast.LambdaExpression")) {
localNode.addError("'" + annotation + "' is not allowed with lambda expressions.");
return;
}
if(isVar && local.initialization instanceof NullLiteral) {
localNode.addError("variable initializer is 'null'");
return;
}
}
}