diff options
-rw-r--r-- | src/eclipseAgent/lombok/eclipse/agent/PatchVal.java | 77 | ||||
-rw-r--r-- | src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java | 19 |
2 files changed, 81 insertions, 15 deletions
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java index 3da37869..c2a362bd 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java @@ -21,9 +21,11 @@ */ package lombok.eclipse.agent; +import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.Annotation; import org.eclipse.jdt.internal.compiler.ast.Expression; import org.eclipse.jdt.internal.compiler.ast.ForeachStatement; +import org.eclipse.jdt.internal.compiler.ast.ImportReference; import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration; import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; @@ -32,8 +34,11 @@ import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.BlockScope; +import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope; +import org.eclipse.jdt.internal.compiler.lookup.ImportBinding; import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding; import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; +import org.eclipse.jdt.internal.compiler.lookup.Scope; import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; import org.eclipse.jdt.internal.compiler.lookup.TypeIds; @@ -84,11 +89,28 @@ public class PatchVal { return true; } - public static boolean couldBe(String key, TypeReference ref) { + public static boolean couldBe(ImportBinding[] imports, String key, TypeReference ref) { String[] keyParts = key.split("\\."); if (ref instanceof SingleTypeReference) { char[] token = ((SingleTypeReference)ref).token; - return matches(keyParts[keyParts.length - 1], token); + if (!matches(keyParts[keyParts.length - 1], token)) return false; + if (imports == null) return true; + top: + for (ImportBinding ib : imports) { + ImportReference ir = ib.reference; + if (ir == null) continue; + if (ir.isStatic()) continue; + boolean star = ((ir.bits & ASTNode.OnDemand) != 0); + int len = keyParts.length - (star ? 1 : 0); + char[][] t = ir.tokens; + if (len != t.length) continue; + for (int i = 0; i < len; i++) { + if (keyParts[i].length() != t[i].length) continue top; + for (int j = 0; j < t[i].length; j++) if (keyParts[i].charAt(j) != t[i][j]) continue top; + } + return true; + } + return false; } if (ref instanceof QualifiedTypeReference) { @@ -104,10 +126,53 @@ public class PatchVal { return false; } - + + public static boolean couldBe(ImportReference[] imports, String key, TypeReference ref) { + String[] keyParts = key.split("\\."); + if (ref instanceof SingleTypeReference) { + char[] token = ((SingleTypeReference)ref).token; + if (!matches(keyParts[keyParts.length - 1], token)) return false; + if (imports == null) return true; + top: + for (ImportReference ir : imports) { + if (ir.isStatic()) continue; + boolean star = ((ir.bits & ASTNode.OnDemand) != 0); + int len = keyParts.length - (star ? 1 : 0); + char[][] t = ir.tokens; + if (len != t.length) continue; + for (int i = 0; i < len; i++) { + if (keyParts[i].length() != t[i].length) continue top; + for (int j = 0; j < t[i].length; j++) if (keyParts[i].charAt(j) != t[i][j]) continue top; + } + return true; + } + return false; + } + + if (ref instanceof QualifiedTypeReference) { + char[][] tokens = ((QualifiedTypeReference)ref).tokens; + if (keyParts.length != tokens.length) return false; + for(int i = 0; i < tokens.length; ++i) { + String part = keyParts[i]; + char[] token = tokens[i]; + if (!matches(part, token)) return false; + } + return true; + } + + return false; + } + private static boolean is(TypeReference ref, BlockScope scope, String key) { - if (!couldBe(key, ref)) return false; - + Scope s = scope.parent; + while (s != null && !(s instanceof CompilationUnitScope)) { + Scope ns = s.parent; + s = ns == s ? null : ns; + } + ImportBinding[] imports = null; + if (s instanceof CompilationUnitScope) imports = ((CompilationUnitScope) s).imports; + if (!couldBe(imports, key, ref)) return false; + TypeBinding resolvedType = ref.resolvedType; if (resolvedType == null) resolvedType = ref.resolveType(scope, false); if (resolvedType == null) return false; @@ -224,7 +289,7 @@ public class PatchVal { boolean val = isVal(forEach.elementVariable, scope); boolean var = isVar(forEach.elementVariable, scope); - if (!(val || var)) return false; + if (!(val || var)) return false; TypeBinding component = getForEachComponentType(forEach.collection, scope); if (component == null) return false; diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java b/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java index 46237dcf..d59b6a2e 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java @@ -45,6 +45,7 @@ import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration; import org.eclipse.jdt.internal.compiler.ast.Annotation; import org.eclipse.jdt.internal.compiler.ast.ForeachStatement; +import org.eclipse.jdt.internal.compiler.ast.ImportReference; import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration; import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.TypeReference; @@ -66,8 +67,8 @@ public class PatchValEclipse { ForeachStatement foreachDecl = (ForeachStatement) astStack[astPtr]; ASTNode init = foreachDecl.collection; if (init == null) return; - boolean val = couldBeVal(foreachDecl.elementVariable.type); - boolean var = couldBeVar(foreachDecl.elementVariable.type); + boolean val = couldBeVal(parser == null ? null : parser.compilationUnit == null ? null : parser.compilationUnit.imports, foreachDecl.elementVariable.type); + boolean var = couldBeVar(parser == null ? null : parser.compilationUnit == null ? null : parser.compilationUnit.imports, foreachDecl.elementVariable.type); if (foreachDecl.elementVariable == null || !(val || var)) return; try { @@ -91,8 +92,8 @@ public class PatchValEclipse { if (!(variableDecl instanceof LocalDeclaration)) return; ASTNode init = variableDecl.initialization; if (init == null) return; - boolean val = couldBeVal(variableDecl.type); - boolean var = couldBeVar(variableDecl.type); + boolean val = couldBeVal(parser == null ? null : parser.compilationUnit == null ? null : parser.compilationUnit.imports, variableDecl.type); + boolean var = couldBeVar(parser == null ? null : parser.compilationUnit == null ? null : parser.compilationUnit.imports, variableDecl.type); if (!(val || var)) return; try { @@ -102,8 +103,8 @@ public class PatchValEclipse { } } - private static boolean couldBeVar(TypeReference type) { - return PatchVal.couldBe("lombok.experimental.var", type) || PatchVal.couldBe("lombok.var", type); + private static boolean couldBeVar(ImportReference[] imports, TypeReference type) { + return PatchVal.couldBe(imports, "lombok.experimental.var", type) || PatchVal.couldBe(imports, "lombok.var", type); } public static void addFinalAndValAnnotationToSingleVariableDeclaration(Object converter, SingleVariableDeclaration out, LocalDeclaration in) { @@ -124,7 +125,7 @@ public class PatchValEclipse { Annotation valAnnotation = null; for (Annotation ann : in.annotations) { - if (couldBeVal(ann.type)) { + if (couldBeVal(null, ann.type)) { found = true; valAnnotation = ann; break; @@ -176,8 +177,8 @@ public class PatchValEclipse { } } - private static boolean couldBeVal(TypeReference type) { - return PatchVal.couldBe("lombok.val", type); + private static boolean couldBeVal(ImportReference[] imports, TypeReference type) { + return PatchVal.couldBe(imports, "lombok.val", type); } public static Modifier createModifier(AST ast, ModifierKeyword keyword, int start, int end) { |