From 7c3724c9dc03684b9e4ecb9b33296c894138add6 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Wed, 25 Jul 2018 22:04:52 +0200 Subject: [Fixes issue #1783] lombok.var / lombok.experimental.var import would be removed by eclipse’s organize imports. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lombok/eclipse/agent/PatchValEclipse.java | 84 ++++++++++++++++------ 1 file changed, 61 insertions(+), 23 deletions(-) (limited to 'src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java') diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java b/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java index d59b6a2e..99447bae 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java @@ -47,9 +47,9 @@ 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.QualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.TypeReference; -import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.parser.Parser; public class PatchValEclipse { @@ -103,6 +103,10 @@ public class PatchValEclipse { } } + private static boolean couldBeVal(ImportReference[] imports, TypeReference type) { + return PatchVal.couldBe(imports, "lombok.val", type); + } + private static boolean couldBeVar(ImportReference[] imports, TypeReference type) { return PatchVal.couldBe(imports, "lombok.experimental.var", type) || PatchVal.couldBe(imports, "lombok.var", type); } @@ -118,17 +122,18 @@ public class PatchValEclipse { } public static void addFinalAndValAnnotationToModifierList(Object converter, List modifiers, AST ast, LocalDeclaration in) { - // First check that 'in' has the final flag on, and a @val / @lombok.val annotation. - if ((in.modifiers & ClassFileConstants.AccFinal) == 0) return; + // First check that 'in' has the final flag on, and a @val / @lombok.val / @var / @lombok.var annotation. if (in.annotations == null) return; boolean found = false; - Annotation valAnnotation = null; - + Annotation valAnnotation = null, varAnnotation = null; for (Annotation ann : in.annotations) { if (couldBeVal(null, ann.type)) { found = true; valAnnotation = ann; - break; + } + if (couldBeVar(null, ann.type)) { + found = true; + varAnnotation = ann; } } @@ -139,10 +144,11 @@ public class PatchValEclipse { if (modifiers == null) return; // This is null only if the project is 1.4 or less. Lombok doesn't work in that. boolean finalIsPresent = false; boolean valIsPresent = false; + boolean varIsPresent = false; for (Object present : modifiers) { if (present instanceof Modifier) { - ModifierKeyword keyword = ((Modifier)present).getKeyword(); + ModifierKeyword keyword = ((Modifier) present).getKeyword(); if (keyword == null) continue; if (keyword.toFlagValue() == Modifier.FINAL) finalIsPresent = true; } @@ -151,20 +157,18 @@ public class PatchValEclipse { Name typeName = ((org.eclipse.jdt.core.dom.Annotation) present).getTypeName(); if (typeName != null) { String fullyQualifiedName = typeName.getFullyQualifiedName(); - if ("val".equals(fullyQualifiedName) || "lombok.val".equals(fullyQualifiedName)) { - valIsPresent = true; - } + if ("val".equals(fullyQualifiedName) || "lombok.val".equals(fullyQualifiedName)) valIsPresent = true; + if ("var".equals(fullyQualifiedName) || "lombok.var".equals(fullyQualifiedName) || "lombok.experimental.var".equals(fullyQualifiedName)) varIsPresent = true; } } } - if (!finalIsPresent) { - modifiers.add( - createModifier(ast, ModifierKeyword.FINAL_KEYWORD, valAnnotation.sourceStart, valAnnotation.sourceEnd)); + if (!finalIsPresent && valAnnotation != null) { + modifiers.add(createModifier(ast, ModifierKeyword.FINAL_KEYWORD, valAnnotation.sourceStart, valAnnotation.sourceEnd)); } - if (!valIsPresent) { - MarkerAnnotation newAnnotation = createValAnnotation(ast, valAnnotation, valAnnotation.sourceStart, valAnnotation.sourceEnd); + if (!valIsPresent && valAnnotation != null) { + MarkerAnnotation newAnnotation = createValVarAnnotation(ast, valAnnotation, valAnnotation.sourceStart, valAnnotation.sourceEnd); try { Reflection.astConverterRecordNodes.invoke(converter, newAnnotation, valAnnotation); Reflection.astConverterRecordNodes.invoke(converter, newAnnotation.getTypeName(), valAnnotation.type); @@ -175,10 +179,19 @@ public class PatchValEclipse { } modifiers.add(newAnnotation); } - } - - private static boolean couldBeVal(ImportReference[] imports, TypeReference type) { - return PatchVal.couldBe(imports, "lombok.val", type); + + if (!varIsPresent && varAnnotation != null) { + MarkerAnnotation newAnnotation = createValVarAnnotation(ast, varAnnotation, varAnnotation.sourceStart, varAnnotation.sourceEnd); + try { + Reflection.astConverterRecordNodes.invoke(converter, newAnnotation, varAnnotation); + Reflection.astConverterRecordNodes.invoke(converter, newAnnotation.getTypeName(), varAnnotation.type); + } catch (IllegalAccessException e) { + throw Lombok.sneakyThrow(e); + } catch (InvocationTargetException e) { + throw Lombok.sneakyThrow(e.getCause()); + } + modifiers.add(newAnnotation); + } } public static Modifier createModifier(AST ast, ModifierKeyword keyword, int start, int end) { @@ -200,7 +213,7 @@ public class PatchValEclipse { return modifier; } - public static MarkerAnnotation createValAnnotation(AST ast, Annotation original, int start, int end) { + public static MarkerAnnotation createValVarAnnotation(AST ast, Annotation original, int start, int end) { MarkerAnnotation out = null; try { out = Reflection.markerAnnotationConstructor.newInstance(ast); @@ -212,13 +225,23 @@ public class PatchValEclipse { throw Lombok.sneakyThrow(e); } + char[][] tokens; + if (original.type instanceof SingleTypeReference) { + tokens = new char[1][]; + tokens[0] = ((SingleTypeReference) original.type).token; + } else if (original.type instanceof QualifiedTypeReference) { + tokens = ((QualifiedTypeReference) original.type).tokens; + } else { + return null; + } + if (out != null) { - SimpleName valName = ast.newSimpleName("val"); + SimpleName valName = ast.newSimpleName(new String(tokens[tokens.length - 1])); valName.setSourceRange(start, end - start + 1); - if (original.type instanceof SingleTypeReference) { + if (tokens.length == 1) { out.setTypeName(valName); setIndex(valName, 1); - } else { + } else if (tokens.length == 2) { SimpleName lombokName = ast.newSimpleName("lombok"); lombokName.setSourceRange(start, end - start + 1); setIndex(lombokName, 1); @@ -227,6 +250,21 @@ public class PatchValEclipse { setIndex(fullName, 1); fullName.setSourceRange(start, end - start + 1); out.setTypeName(fullName); + } else { + SimpleName lombokName = ast.newSimpleName("lombok"); + lombokName.setSourceRange(start, end - start + 1); + SimpleName experimentalName = ast.newSimpleName("experimental"); + lombokName.setSourceRange(start, end - start + 1); + setIndex(lombokName, 1); + setIndex(experimentalName, 2); + setIndex(valName, 3); + QualifiedName lombokExperimentalName = ast.newQualifiedName(lombokName, experimentalName); + lombokExperimentalName.setSourceRange(start, end - start + 1); + setIndex(lombokExperimentalName, 1); + QualifiedName fullName = ast.newQualifiedName(lombokExperimentalName, valName); + setIndex(fullName, 1); + fullName.setSourceRange(start, end - start + 1); + out.setTypeName(fullName); } out.setSourceRange(start, end - start + 1); } -- cgit