diff options
Diffstat (limited to 'src/eclipseAgent/lombok/eclipse/agent')
3 files changed, 116 insertions, 11 deletions
diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java index 756c23fa..c560f002 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java +++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java @@ -103,6 +103,7 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { patchIdentifierEndReparse(sm); patchRetrieveEllipsisStartPosition(sm); patchRetrieveRightBraceOrSemiColonPosition(sm); + patchRetrieveProperRightBracketPosition(sm); patchSetGeneratedFlag(sm); patchDomAstReparseIssues(sm); patchHideGeneratedNodes(sm); @@ -445,6 +446,16 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { // .transplant().request(StackRequest.RETURN_VALUE, StackRequest.PARAM2).build()); } + private static void patchRetrieveProperRightBracketPosition(ScriptManager sm) { + sm.addScript(ScriptBuilder.wrapMethodCall() + .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "extractSubArrayType", "org.eclipse.jdt.core.dom.ArrayType", "org.eclipse.jdt.core.dom.ArrayType", "int", "int")) + .methodToWrap(new Hook("org.eclipse.jdt.core.dom.ASTConverter", "retrieveProperRightBracketPosition", "int", "int", "int")) + .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "fixRetrieveProperRightBracketPosition", "int", "int", "org.eclipse.jdt.core.dom.ArrayType")) + .requestExtra(StackRequest.PARAM1) + .transplant() + .build()); + } + private static void patchSetGeneratedFlag(ScriptManager sm) { sm.addScript(ScriptBuilder.addField() .targetClass("org.eclipse.jdt.internal.compiler.ast.ASTNode") @@ -564,6 +575,22 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "setIsGeneratedFlagForName", "void", "org.eclipse.jdt.core.dom.Name", "java.lang.Object")) .transplant().build()); + + sm.addScript(ScriptBuilder.wrapMethodCall() + .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "setTypeNameForAnnotation", "void", "org.eclipse.jdt.internal.compiler.ast.Annotation", "org.eclipse.jdt.core.dom.Annotation")) + .methodToWrap(new Hook("org.eclipse.jdt.core.dom.SimpleName", "<init>", "void", "org.eclipse.jdt.core.dom.AST")) + .requestExtra(StackRequest.PARAM1) + .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "setIsGeneratedFlagForName", "void", + "org.eclipse.jdt.core.dom.Name", "java.lang.Object")) + .transplant().build()); + + sm.addScript(ScriptBuilder.wrapMethodCall() + .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "setTypeNameForAnnotation", "void", "org.eclipse.jdt.internal.compiler.ast.Annotation", "org.eclipse.jdt.core.dom.Annotation")) + .methodToWrap(new Hook("org.eclipse.jdt.core.dom.QualifiedName", "<init>", "void", "org.eclipse.jdt.core.dom.AST")) + .requestExtra(StackRequest.PARAM1) + .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "setIsGeneratedFlagForName", "void", + "org.eclipse.jdt.core.dom.Name", "java.lang.Object")) + .transplant().build()); } private static void patchAvoidReparsingGeneratedCode(ScriptManager sm) { diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java b/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java index 02760e35..1a287d93 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java @@ -29,11 +29,14 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import lombok.core.AST.Kind; +import lombok.eclipse.Eclipse; import lombok.eclipse.EclipseAST; import lombok.eclipse.EclipseNode; import lombok.eclipse.TransformEclipseAST; @@ -67,6 +70,7 @@ import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding; import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.ClassScope; +import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers; import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding; @@ -214,7 +218,7 @@ public class PatchDelegate { addAllMethodBindings(methodsToExclude, cla.type.resolveType(decl.initializerScope), new HashSet<String>(), field.name, ann); } - Set<String> banList = new HashSet<String>(); + Set<String> banList = findAlreadyImplementedMethods(decl); for (BindingTuple excluded : methodsToExclude) banList.add(printSig(excluded.parameterized)); if (rawTypes.isEmpty()) { @@ -283,8 +287,8 @@ public class PatchDelegate { for (ClassLiteralAccess cla : excludedRawTypes) { addAllMethodBindings(methodsToExclude, cla.type.resolveType(decl.initializerScope), new HashSet<String>(), method.selector, ann); } - - Set<String> banList = new HashSet<String>(); + + Set<String> banList = findAlreadyImplementedMethods(decl); for (BindingTuple excluded : methodsToExclude) banList.add(printSig(excluded.parameterized)); if (rawTypes.isEmpty()) { @@ -317,6 +321,8 @@ public class PatchDelegate { private static boolean isDelegate(Annotation ann, TypeDeclaration decl) { if (ann.type == null) return false; + if (!charArrayEquals("Delegate", ann.type.getLastToken())) return false; + TypeBinding tb = ann.type.resolveType(decl.initializerScope); if (tb == null) return false; if (!charArrayEquals("lombok", tb.qualifiedPackageName()) && !charArrayEquals("lombok.experimental", tb.qualifiedPackageName())) return false; @@ -764,6 +770,21 @@ public class PatchDelegate { } } + private static Set<String> findAlreadyImplementedMethods(TypeDeclaration decl) { + Set<String> sigs = new HashSet<String>(); + for (AbstractMethodDeclaration md : decl.methods) { + if (md.isStatic()) continue; + if ((md.modifiers & ClassFileConstants.AccBridge) != 0) continue; + if (md.isConstructor()) continue; + if ((md.modifiers & ExtraCompilerModifiers.AccDefaultAbstract) != 0) continue; + if ((md.modifiers & ClassFileConstants.AccPublic) == 0) continue; + if ((md.modifiers & ClassFileConstants.AccSynthetic) != 0) continue; + + sigs.add(printSig(md, decl.scope)); + } + return sigs; + } + private static final char[] STRING_LOMBOK = new char[] {'l', 'o', 'm', 'b', 'o', 'k'}; private static final char[] STRING_EXPERIMENTAL = new char[] {'e', 'x', 'p', 'e', 'r', 'i', 'm', 'e', 'n', 't', 'a', 'l'}; private static final char[] STRING_DELEGATE = new char[] {'D', 'e', 'l', 'e', 'g', 'a', 't', 'e'}; @@ -839,6 +860,54 @@ public class PatchDelegate { return signature.toString(); } + private static String printSig(AbstractMethodDeclaration md, ClassScope scope) { + StringBuilder signature = new StringBuilder(); + + signature.append(md.selector); + signature.append("("); + boolean first = true; + if (md.arguments != null) { + TypeParameter[] typeParameters = md.typeParameters(); + Map<String, TypeParameter> typeParametersMap = new HashMap<String, TypeParameter>(); + if (typeParameters != null) { + for (TypeParameter typeParameter : typeParameters) { + typeParametersMap.put(new String(typeParameter.name), typeParameter); + } + } + + for (Argument argument : md.arguments) { + TypeBinding typeBinding = makeTypeBinding(argument.type, typeParametersMap, scope); + + if (!first) signature.append(", "); + first = false; + signature.append(typeBindingToSignature(typeBinding)); + } + } + signature.append(")"); + + return signature.toString(); + } + + private static TypeBinding makeTypeBinding(TypeReference typeReference, Map<String, TypeParameter> typeParametersMap, ClassScope scope) { + char[][] typeName = typeReference.getTypeName(); + String typeNameString = Eclipse.toQualifiedName(typeName); + + TypeParameter typeParameter = typeParametersMap.get(typeNameString); + if (typeParameter != null) { + if (typeParameter.type != null) { + typeName = typeParameter.type.getTypeName(); + } else { + typeName = TypeConstants.JAVA_LANG_OBJECT; + } + } + + TypeBinding typeBinding = scope.getType(typeName, typeName.length); + if (typeReference.dimensions() > 0) { + typeBinding = scope.createArrayType(typeBinding, typeReference.dimensions()); + } + return typeBinding; + } + private static String typeBindingToSignature(TypeBinding binding) { binding = binding.erasure(); if (binding != null && binding.isBaseType()) { diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java index 056852c8..f22e78a8 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java @@ -35,11 +35,13 @@ import org.eclipse.jdt.internal.compiler.ast.FunctionalExpression; import org.eclipse.jdt.internal.compiler.ast.ImportReference; import org.eclipse.jdt.internal.compiler.ast.LambdaExpression; import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration; +import org.eclipse.jdt.internal.compiler.ast.MessageSend; import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.ast.TypeReference; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; +import org.eclipse.jdt.internal.compiler.impl.Constant; import org.eclipse.jdt.internal.compiler.impl.ReferenceContext; import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding; import org.eclipse.jdt.internal.compiler.lookup.Binding; @@ -227,14 +229,16 @@ public class PatchVal { boolean var = isVar(local, scope); if (!(val || var)) return false; - StackTraceElement[] st = new Throwable().getStackTrace(); - for (int i = 0; i < st.length - 2 && i < 10; i++) { - if (st[i].getClassName().equals("lombok.launch.PatchFixesHider$Val")) { - boolean valInForStatement = val && - st[i + 1].getClassName().equals("org.eclipse.jdt.internal.compiler.ast.LocalDeclaration") && - st[i + 2].getClassName().equals("org.eclipse.jdt.internal.compiler.ast.ForStatement"); - if (valInForStatement) return false; - break; + if (val) { + StackTraceElement[] st = new Throwable().getStackTrace(); + for (int i = 0; i < st.length - 2 && i < 10; i++) { + if (st[i].getClassName().equals("lombok.launch.PatchFixesHider$Val")) { + boolean valInForStatement = + st[i + 1].getClassName().equals("org.eclipse.jdt.internal.compiler.ast.LocalDeclaration") && + st[i + 2].getClassName().equals("org.eclipse.jdt.internal.compiler.ast.ForStatement"); + if (valInForStatement) return false; + break; + } } } @@ -264,6 +268,7 @@ public class PatchVal { } TypeBinding resolved = null; + Constant oldConstant = init.constant; try { resolved = decomponent ? getForEachComponentType(init, scope) : resolveForExpression(init, scope); } catch (NullPointerException e) { @@ -280,6 +285,10 @@ public class PatchVal { } catch (Exception e) { // Some type thing failed. } + } else { + if (init instanceof MessageSend && ((MessageSend) init).actualReceiverType == null) { + init.constant = oldConstant; + } } } |