aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/lombok/javac/Javac.java14
-rw-r--r--src/core/lombok/javac/handlers/HandleVal.java114
2 files changed, 72 insertions, 56 deletions
diff --git a/src/core/lombok/javac/Javac.java b/src/core/lombok/javac/Javac.java
index 6d9800ab..f4e3f141 100644
--- a/src/core/lombok/javac/Javac.java
+++ b/src/core/lombok/javac/Javac.java
@@ -36,6 +36,7 @@ import lombok.core.TypeResolver;
import lombok.core.AST.Kind;
import lombok.core.AnnotationValues.AnnotationValue;
+import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCAssign;
import com.sun.tools.javac.tree.JCTree.JCExpression;
@@ -61,7 +62,18 @@ public class Javac {
*/
public static boolean annotationTypeMatches(Class<? extends Annotation> type, JavacNode node) {
if (node.getKind() != Kind.ANNOTATION) return false;
- String typeName = ((JCAnnotation)node.get()).annotationType.toString();
+ return typeMatches(type, node, ((JCAnnotation)node.get()).annotationType);
+ }
+
+ /**
+ * Checks if the given TypeReference node is likely to be a reference to the provided class.
+ *
+ * @param type An actual type. This method checks if {@code typeNode} is likely to be a reference to this type.
+ * @param node A Lombok AST node. Any node in the appropriate compilation unit will do (used to get access to import statements).
+ * @param typeNode A type reference to check.
+ */
+ public static boolean typeMatches(Class<?> type, JavacNode node, JCTree typeNode) {
+ String typeName = typeNode.toString();
TypeLibrary library = new TypeLibrary();
library.addType(type.getName());
diff --git a/src/core/lombok/javac/handlers/HandleVal.java b/src/core/lombok/javac/handlers/HandleVal.java
index 98142a3b..14b0b44e 100644
--- a/src/core/lombok/javac/handlers/HandleVal.java
+++ b/src/core/lombok/javac/handlers/HandleVal.java
@@ -21,6 +21,8 @@
*/
package lombok.javac.handlers;
+import lombok.val;
+import lombok.javac.Javac;
import lombok.javac.JavacASTAdapter;
import lombok.javac.JavacASTVisitor;
import lombok.javac.JavacNode;
@@ -43,71 +45,73 @@ public class HandleVal extends JavacASTAdapter {
}
@Override public void visitLocal(JavacNode localNode, JCVariableDecl local) {
- if (local.vartype != null && local.vartype.toString().equals("val")) {
- JCExpression rhsOfEnhancedForLoop = null;
- if (local.init == null) {
- JCTree parentRaw = localNode.directUp().get();
- if (parentRaw instanceof JCEnhancedForLoop) {
- JCEnhancedForLoop efl = (JCEnhancedForLoop) parentRaw;
- if (efl.var == local) rhsOfEnhancedForLoop = efl.expr;
- }
- }
-
- if (rhsOfEnhancedForLoop == null && local.init == null) {
- localNode.addError("'val' on a local variable requires an initializer expression");
- return;
+ if (local.vartype == null || (!local.vartype.toString().equals("val") && !local.vartype.toString().equals("lombok.val"))) return;
+
+ if (!Javac.typeMatches(val.class, localNode, local.vartype)) return;
+
+ JCExpression rhsOfEnhancedForLoop = null;
+ if (local.init == null) {
+ JCTree parentRaw = localNode.directUp().get();
+ if (parentRaw instanceof JCEnhancedForLoop) {
+ JCEnhancedForLoop efl = (JCEnhancedForLoop) parentRaw;
+ if (efl.var == local) rhsOfEnhancedForLoop = efl.expr;
}
-
- if (local.init instanceof JCNewArray && ((JCNewArray)local.init).elemtype == null) {
- localNode.addError("'val' is not compatible with array initializer expressions. Use the full form (new int[] { ... } instead of just { ... })");
- return;
+ }
+
+ if (rhsOfEnhancedForLoop == null && local.init == null) {
+ localNode.addError("'val' on a local variable requires an initializer expression");
+ return;
+ }
+
+ if (local.init instanceof JCNewArray && ((JCNewArray)local.init).elemtype == null) {
+ localNode.addError("'val' is not compatible with array initializer expressions. Use the full form (new int[] { ... } instead of just { ... })");
+ return;
+ }
+
+ local.mods.flags |= Flags.FINAL;
+ local.vartype = JavacResolution.createJavaLangObject(localNode.getTreeMaker(), localNode.getAst());
+
+ Type type;
+ try {
+ if (rhsOfEnhancedForLoop == null) {
+ if (local.init.type == null) {
+ JavacResolution resolver = new JavacResolution(localNode.getContext());
+ type = ((JCExpression) resolver.resolveMethodMember(localNode).get(local.init)).type;
+ } else {
+ type = local.init.type;
+ }
+ } else {
+ if (rhsOfEnhancedForLoop.type == null) {
+ JavacResolution resolver = new JavacResolution(localNode.getContext());
+ type = ((JCExpression) resolver.resolveMethodMember(localNode.directUp()).get(rhsOfEnhancedForLoop)).type;
+ } else {
+ type = rhsOfEnhancedForLoop.type;
+ }
}
- local.mods.flags |= Flags.FINAL;
- local.vartype = JavacResolution.createJavaLangObject(localNode.getTreeMaker(), localNode.getAst());
-
- Type type;
try {
- if (rhsOfEnhancedForLoop == null) {
- if (local.init.type == null) {
- JavacResolution resolver = new JavacResolution(localNode.getContext());
- type = ((JCExpression) resolver.resolveMethodMember(localNode).get(local.init)).type;
- } else {
- type = local.init.type;
- }
+ JCExpression replacement;
+
+ if (rhsOfEnhancedForLoop != null) {
+ Type componentType = JavacResolution.ifTypeIsIterableToComponent(type, localNode.getAst());
+ if (componentType == null) replacement = JavacResolution.createJavaLangObject(localNode.getTreeMaker(), localNode.getAst());
+ else replacement = JavacResolution.typeToJCTree(componentType, localNode.getTreeMaker(), localNode.getAst(), false);
} else {
- if (rhsOfEnhancedForLoop.type == null) {
- JavacResolution resolver = new JavacResolution(localNode.getContext());
- type = ((JCExpression) resolver.resolveMethodMember(localNode.directUp()).get(rhsOfEnhancedForLoop)).type;
- } else {
- type = rhsOfEnhancedForLoop.type;
- }
+ replacement = JavacResolution.typeToJCTree(type, localNode.getTreeMaker(), localNode.getAst(), false);
}
- try {
- JCExpression replacement;
-
- if (rhsOfEnhancedForLoop != null) {
- Type componentType = JavacResolution.ifTypeIsIterableToComponent(type, localNode.getAst());
- if (componentType == null) replacement = JavacResolution.createJavaLangObject(localNode.getTreeMaker(), localNode.getAst());
- else replacement = JavacResolution.typeToJCTree(componentType, localNode.getTreeMaker(), localNode.getAst(), false);
- } else {
- replacement = JavacResolution.typeToJCTree(type, localNode.getTreeMaker(), localNode.getAst(), false);
- }
-
- if (replacement != null) {
- local.vartype = replacement;
- localNode.getAst().setChanged();
- }
- else local.vartype = JavacResolution.createJavaLangObject(localNode.getTreeMaker(), localNode.getAst());;
- } catch (JavacResolution.TypeNotConvertibleException e) {
- localNode.addError("Cannot use 'val' here because initializer expression does not have a representable type: " + e.getMessage());
- local.vartype = JavacResolution.createJavaLangObject(localNode.getTreeMaker(), localNode.getAst());;
+ if (replacement != null) {
+ local.vartype = replacement;
+ localNode.getAst().setChanged();
}
- } catch (RuntimeException e) {
+ else local.vartype = JavacResolution.createJavaLangObject(localNode.getTreeMaker(), localNode.getAst());;
+ } catch (JavacResolution.TypeNotConvertibleException e) {
+ localNode.addError("Cannot use 'val' here because initializer expression does not have a representable type: " + e.getMessage());
local.vartype = JavacResolution.createJavaLangObject(localNode.getTreeMaker(), localNode.getAst());;
- throw e;
}
+ } catch (RuntimeException e) {
+ local.vartype = JavacResolution.createJavaLangObject(localNode.getTreeMaker(), localNode.getAst());;
+ throw e;
}
}
}