diff options
29 files changed, 510 insertions, 147 deletions
diff --git a/buildScripts/create-eclipse-project.ant.xml b/buildScripts/create-eclipse-project.ant.xml index 513ffe8f..da91964f 100644 --- a/buildScripts/create-eclipse-project.ant.xml +++ b/buildScripts/create-eclipse-project.ant.xml @@ -27,7 +27,7 @@ This buildfile is part of projectlombok.org. It creates the infrastructure neede <target name="eclipse" depends="eclipse.projectfiles, eclipse.testtarget.default" description="Downloads dependencies, create eclipse project files, as well as debug/run test targets. Open this directory as project in eclipse (via import... existing projects)" /> <target name="eclipse.projectfiles" depends="deps"> - <ivy:eclipsegen source="1.6"> + <ivy:eclipsegen source="1.6" srcout="bin/main"> <srcdir dir="src/core" /> <srcdir dir="src/core8" /> <srcdir dir="src/launch" /> @@ -35,7 +35,7 @@ This buildfile is part of projectlombok.org. It creates the infrastructure neede <srcdir dir="src/eclipseAgent" /> <srcdir dir="src/installer" /> <srcdir dir="src/delombok" /> - <srcdir dir="src/stubs" /> + <srcdir dir="src/stubs" srcout="bin/stubs" /> <srcdir dir="src/support" /> <srcdir dir="experimental/src" /> <srcdir dir="test/transform/src" /> @@ -116,7 +116,7 @@ This buildfile is part of projectlombok.org. It creates the infrastructure neede <condition property="inputs.jvmtarget" value="1.6"><equals arg1="${inputs.jvmtarget.raw}" arg2="6" /></condition> <condition property="inputs.jvmtarget" value="1.8"><equals arg1="${inputs.jvmtarget.raw}" arg2="8" /></condition> - <property name="inputs" value="${inputs.jvmtarget.raw}" /> + <property name="inputs.jvmtarget" value="${inputs.jvmtarget.raw}" /> <condition property="inputs.bootpath" value="${jdk6-rt.loc}"><equals arg1="${inputs.jvmtarget.raw}" arg2="6" /></condition> <condition property="inputs.bootpath" value="${jdk8-rt.loc}"><equals arg1="${inputs.jvmtarget.raw}" arg2="8" /></condition> @@ -127,6 +127,12 @@ This buildfile is part of projectlombok.org. It creates the infrastructure neede <target name="eclipse.testtarget.javac" depends="compile.support" description="Makes an eclipse launch target for running the tests for javac"> <eclipse.testtarget.conf.jvmtarget question="Which javac do you want to target? Enter a version, such as '11'." validargs="8,11,13,14,15" /> + <local name="inputs.confcp" /> + <condition property="inputs.confcp" value="NONE"> + <not><equals arg1="8" arg2="${inputs.jvmtarget.raw}" /></not> + </condition> + <property name="inputs.confcp" refid="cp.javac8" /> + <java classname="lombok.eclipseCreate.CreateEclipseDebugTarget" failonerror="true"> <classpath> <path refid="cp.buildtools" /> diff --git a/buildScripts/setup.ant.xml b/buildScripts/setup.ant.xml index 9b96240d..ed835960 100644 --- a/buildScripts/setup.ant.xml +++ b/buildScripts/setup.ant.xml @@ -106,7 +106,7 @@ This buildfile is part of projectlombok.org. It sets up the build itself. <target name="-ipp.load" depends="-ipp.download"> <taskdef classpath="lib/ivyplusplus.jar" resource="com/zwitserloot/ivyplusplus/antlib.xml" uri="antlib:com.zwitserloot.ivyplusplus" /> - <ivy:ensureippversion version="1.36" property="ivyplusplus.minimumAvailable" /> + <ivy:ensureippversion version="1.38" property="ivyplusplus.minimumAvailable" /> </target> <target name="-ipp.redownload" unless="ivyplusplus.minimumAvailable"> diff --git a/buildScripts/vm-finder.ant.xml b/buildScripts/vm-finder.ant.xml index 2b2c4c4c..a15d8ed0 100644 --- a/buildScripts/vm-finder.ant.xml +++ b/buildScripts/vm-finder.ant.xml @@ -38,7 +38,7 @@ This buildfile is part of projectlombok.org. It contains platform specific code <condition property="jvm.loc" value="${jvm.loc.force}"> <and> <isset property="jvm.loc.force" /> - <not><matches string="${jvm.loc.force}" pattern="^\$\{jvm[0-9\.]+\.loc\}$" /></not> + <not><matches string="${jvm.loc.force}" pattern="^\$\{jvm\.locations\.j[0-9\.]+\}$" /></not> </and> </condition> <condition property="jvm.loc.invalid"> diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index 3246367c..d85c2ee8 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -2474,18 +2474,7 @@ public class EclipseHandlerUtil { } public static NameReference createNameReference(String name, Annotation source) { - int pS = source.sourceStart, pE = source.sourceEnd; - long p = (long)pS << 32 | pE; - - char[][] nameTokens = fromQualifiedName(name); - long[] pos = new long[nameTokens.length]; - Arrays.fill(pos, p); - - QualifiedNameReference nameReference = new QualifiedNameReference(nameTokens, pos, pS, pE); - nameReference.statementEnd = pE; - - setGeneratedBy(nameReference, source); - return nameReference; + return generateQualifiedNameRef(source, fromQualifiedName(name)); } private static long[] copy(long[] array) { @@ -2640,6 +2629,10 @@ public class EclipseHandlerUtil { return ref; } + public static TypeReference createTypeReference(String typeName, ASTNode source) { + return generateQualifiedTypeRef(source, fromQualifiedName(typeName)); + } + public static String getDocComment(CompilationUnitDeclaration cud, ASTNode node) { ICompilationUnit compilationUnit = cud.compilationResult.compilationUnit; if (node instanceof FieldDeclaration) { @@ -2673,7 +2666,7 @@ public class EclipseHandlerUtil { } } } - + public static String getSignature(TypeDeclaration type, AbstractMethodDeclaration methodDeclaration) { StringBuilder sb = new StringBuilder(); sb.append(type.name); diff --git a/src/core/lombok/eclipse/handlers/HandleLog.java b/src/core/lombok/eclipse/handlers/HandleLog.java index a0e431e5..8297426d 100644 --- a/src/core/lombok/eclipse/handlers/HandleLog.java +++ b/src/core/lombok/eclipse/handlers/HandleLog.java @@ -22,11 +22,9 @@ package lombok.eclipse.handlers; import static lombok.core.handlers.HandlerUtil.handleFlagUsage; -import static lombok.eclipse.Eclipse.fromQualifiedName; import static lombok.eclipse.handlers.EclipseHandlerUtil.*; import java.lang.reflect.Modifier; -import java.util.Arrays; import java.util.List; import org.eclipse.jdt.internal.compiler.ast.Annotation; @@ -35,7 +33,6 @@ import org.eclipse.jdt.internal.compiler.ast.Expression; import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; import org.eclipse.jdt.internal.compiler.ast.MessageSend; import org.eclipse.jdt.internal.compiler.ast.NullLiteral; -import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.StringLiteral; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; @@ -156,19 +153,6 @@ public class HandleLog { return fieldDecl; } - public static TypeReference createTypeReference(String typeName, Annotation source) { - int pS = source.sourceStart, pE = source.sourceEnd; - long p = (long) pS << 32 | pE; - - char[][] typeNameTokens = fromQualifiedName(typeName); - long[] pos = new long[typeNameTokens.length]; - Arrays.fill(pos, p); - - TypeReference typeReference = new QualifiedTypeReference(typeNameTokens, pos); - setGeneratedBy(typeReference, source); - return typeReference; - } - private static final Expression[] createFactoryParameters(ClassLiteralAccess loggingType, Annotation source, List<LogFactoryParameter> parameters, Expression loggerTopic) { Expression[] expressions = new Expression[parameters.size()]; int pS = source.sourceStart, pE = source.sourceEnd; diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java index b1e7c419..79b7e816 100644 --- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java @@ -741,6 +741,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> { } out.statements = body.isEmpty() ? null : body.toArray(new Statement[0]); + out.traverse(new SetGeneratedByVisitor(source), (ClassScope) null); return out; } diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java index 6a271973..d0769e83 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java +++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java @@ -104,6 +104,7 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { patchRetrieveEllipsisStartPosition(sm); patchRetrieveRightBraceOrSemiColonPosition(sm); patchRetrieveProperRightBracketPosition(sm); + patchRetrieveStartBlockPosition(sm); patchSetGeneratedFlag(sm); patchDomAstReparseIssues(sm); patchHideGeneratedNodes(sm); @@ -415,6 +416,13 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { .transplant().request(StackRequest.RETURN_VALUE, StackRequest.PARAM2).build()); } + private static void patchRetrieveStartBlockPosition(ScriptManager sm) { + sm.addScript(ScriptBuilder.wrapReturnValue() + .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "retrieveStartBlockPosition")) + .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "fixRetrieveStartBlockPosition", "int", "int", "int")) + .transplant().request(StackRequest.RETURN_VALUE, StackRequest.PARAM2).build()); + } + private static void patchRetrieveRightBraceOrSemiColonPosition(ScriptManager sm) { sm.addScript(ScriptBuilder.wrapMethodCall() .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convert", "org.eclipse.jdt.core.dom.ASTNode", "boolean", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration")) @@ -451,7 +459,15 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { 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")) + .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "fixRetrieveProperRightBracketPosition", "int", "int", "org.eclipse.jdt.core.dom.Type")) + .requestExtra(StackRequest.PARAM1) + .transplant() + .build()); + + sm.addScript(ScriptBuilder.wrapMethodCall() + .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convertToArray", "org.eclipse.jdt.core.dom.ArrayType", "org.eclipse.jdt.core.dom.Type", "int", "int", "int", "org.eclipse.jdt.internal.compiler.ast.Annotation[][]")) + .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.Type")) .requestExtra(StackRequest.PARAM1) .transplant() .build()); @@ -508,6 +524,8 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convertToVariableDeclarationFragment", "org.eclipse.jdt.core.dom.VariableDeclarationFragment", "org.eclipse.jdt.internal.compiler.ast.FieldDeclaration")) .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convertToVariableDeclarationFragment", "org.eclipse.jdt.core.dom.VariableDeclarationFragment", "org.eclipse.jdt.internal.compiler.ast.LocalDeclaration")) .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convertToVariableDeclarationStatement", "org.eclipse.jdt.core.dom.VariableDeclarationStatement", "org.eclipse.jdt.internal.compiler.ast.LocalDeclaration")) + .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "createBaseType", "org.eclipse.jdt.core.dom.Type", "org.eclipse.jdt.internal.compiler.ast.TypeReference", "long[]", "org.eclipse.jdt.internal.compiler.ast.Annotation[][]", "char[][]", "int", "int", "boolean")) + .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "createQualifiedType", "org.eclipse.jdt.core.dom.QualifiedType", "org.eclipse.jdt.internal.compiler.ast.TypeReference", "long[]", "org.eclipse.jdt.internal.compiler.ast.Annotation[][]", "char[][]", "int", "org.eclipse.jdt.core.dom.Type")) /* Targets above are only patched because the resulting dom nodes should be marked if generated. */ .request(StackRequest.PARAM1, StackRequest.RETURN_VALUE) .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "setIsGeneratedFlag", "void", @@ -543,6 +561,43 @@ 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", "convertType", "org.eclipse.jdt.core.dom.Type", "org.eclipse.jdt.internal.compiler.ast.TypeReference")) + .methodToWrap(new Hook("org.eclipse.jdt.core.dom.PrimitiveType", "<init>", "void", "org.eclipse.jdt.core.dom.AST")) + .requestExtra(StackRequest.PARAM1) + .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "setIsGeneratedFlag", "void", + "org.eclipse.jdt.core.dom.ASTNode", "org.eclipse.jdt.internal.compiler.ast.ASTNode")) + .transplant() + .build()); + + sm.addScript(ScriptBuilder.wrapMethodCall() + .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convertType", "org.eclipse.jdt.core.dom.Type", "org.eclipse.jdt.internal.compiler.ast.TypeReference")) + .methodToWrap(new Hook("org.eclipse.jdt.core.dom.SimpleType", "<init>", "void", "org.eclipse.jdt.core.dom.AST")) + .requestExtra(StackRequest.PARAM1) + .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "setIsGeneratedFlag", "void", + "org.eclipse.jdt.core.dom.ASTNode", "org.eclipse.jdt.internal.compiler.ast.ASTNode")) + .transplant() + .build()); + + sm.addScript(ScriptBuilder.wrapMethodCall() + .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convertType", "org.eclipse.jdt.core.dom.Type", "org.eclipse.jdt.internal.compiler.ast.TypeReference")) + .methodToWrap(new Hook("org.eclipse.jdt.core.dom.ParameterizedType", "<init>", "void", "org.eclipse.jdt.core.dom.AST")) + .requestExtra(StackRequest.PARAM1) + .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "setIsGeneratedFlag", "void", + "org.eclipse.jdt.core.dom.ASTNode", "org.eclipse.jdt.internal.compiler.ast.ASTNode")) + .transplant() + .build()); + + sm.addScript(ScriptBuilder.wrapMethodCall() + .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convertType", "org.eclipse.jdt.core.dom.Type", "org.eclipse.jdt.internal.compiler.ast.TypeReference")) + .methodToWrap(new Hook("org.eclipse.jdt.core.dom.QualifiedType", "<init>", "void", "org.eclipse.jdt.core.dom.AST")) + .requestExtra(StackRequest.PARAM1) + .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "setIsGeneratedFlag", "void", + "org.eclipse.jdt.core.dom.ASTNode", "org.eclipse.jdt.internal.compiler.ast.ASTNode")) + .transplant() + .build()); /* Set generated flag for QualifiedNames */ sm.addScript(ScriptBuilder.wrapMethodCall() diff --git a/src/eclipseAgent/lombok/eclipse/agent/ExtensionMethodCompletionProposal.java b/src/eclipseAgent/lombok/eclipse/agent/ExtensionMethodCompletionProposal.java index 46ce63f9..833a8226 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/ExtensionMethodCompletionProposal.java +++ b/src/eclipseAgent/lombok/eclipse/agent/ExtensionMethodCompletionProposal.java @@ -22,10 +22,15 @@ package lombok.eclipse.agent; import static org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.AccStatic; +import static org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.AccVarargs; import java.util.Arrays; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jdt.core.CompletionProposal; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.Signature; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.codeassist.CompletionEngine; import org.eclipse.jdt.internal.codeassist.InternalCompletionProposal; @@ -35,16 +40,29 @@ import org.eclipse.jdt.internal.codeassist.complete.CompletionOnSingleNameRefere import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; +import org.eclipse.jdt.internal.core.NameLookup; public class ExtensionMethodCompletionProposal extends InternalCompletionProposal { + private char[] fullSignature; + private char[][] parameterNames; + public ExtensionMethodCompletionProposal(final int replacementOffset) { super(CompletionProposal.METHOD_REF, replacementOffset - 1); } public void setMethodBinding(final MethodBinding method, final ASTNode node) { + // Add proposal parameter names, sometimes its empty... + if (method.parameterNames != null && method.parameterNames.length > 0) { + setParameterNames(Arrays.copyOfRange(method.parameterNames, 1, method.parameterNames.length)); + } else { + // Copy signature for parameter name resolution, this is more reliable but slower + fullSignature = CompletionEngine.getSignature(method); + } + MethodBinding original = method.original(); TypeBinding[] parameters = Arrays.copyOf(method.parameters, method.parameters.length); method.parameters = Arrays.copyOfRange(method.parameters, 1, method.parameters.length); + TypeBinding[] originalParameters = null; if (original != method) { originalParameters = Arrays.copyOf(method.original().parameters, method.original().parameters.length); @@ -76,6 +94,10 @@ public class ExtensionMethodCompletionProposal extends InternalCompletionProposa setName(method.selector); setCompletion(completion); setFlags(method.modifiers & (~AccStatic)); + // Remove varargs flag if it is the only parameter + if (method.isVarargs() && length == 0) { + setFlags(getFlags() & (~AccVarargs)); + } int index = node.sourceEnd + 1; if (node instanceof CompletionOnQualifiedNameReference) { index -= ((CompletionOnQualifiedNameReference) node).completionIdentifier.length; @@ -96,4 +118,58 @@ public class ExtensionMethodCompletionProposal extends InternalCompletionProposa method.original().parameters = originalParameters; } } + + @Override + public char[][] findParameterNames(IProgressMonitor monitor) { + if (parameterNames != null) { + return parameterNames; + } + + NameLookup.Answer answer = this.nameLookup.findType( + new String(this.declarationTypeName), + new String(this.declarationPackageName), + false, + NameLookup.ACCEPT_CLASSES & NameLookup.ACCEPT_INTERFACES, + true/* consider secondary types */, + false/* do NOT wait for indexes */, + false/*don't check restrictions*/, + null); + + if (answer != null && answer.type != null) { + char[][] parameterTypes = Signature.getParameterTypes(fullSignature); + + String[] args = new String[parameterTypes.length]; + for (int i = 0; i < parameterTypes.length; i++) { + args[i] = new String(parameterTypes[i]); + } + IMethod method = answer.type.getMethod(new String(this.getName()), args); + IMethod[] methods = answer.type.findMethods(method); + if (methods != null && methods.length > 0) { + method = methods[0]; + } + if (method != null) { + try { + String[] parameterNames = method.getParameterNames(); + char[][] parameterNamesAsChar = new char[parameterNames.length - 1][]; + for (int i = 0; i < parameterNamesAsChar.length; i++) { + parameterNamesAsChar[i] = parameterNames[i + 1].toCharArray(); + } + setParameterNames(parameterNamesAsChar); + } catch (JavaModelException e) { + // Nope + } + } + } + // Seems like we failed, fallback + if (parameterNames == null) { + parameterNames = super.findParameterNames(monitor); + } + return parameterNames; + } + + @Override + public void setParameterNames(char[][] parameterNames) { + this.parameterNames = parameterNames; + super.setParameterNames(parameterNames); + } } diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java index fcc76059..0b33ff0a 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java @@ -24,6 +24,7 @@ package lombok.eclipse.agent; import static lombok.eclipse.handlers.EclipseHandlerUtil.createAnnotation; import java.lang.ref.WeakReference; +import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -58,6 +59,7 @@ 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.MethodBinding; +import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding; import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding; import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; import org.eclipse.jdt.internal.compiler.lookup.Scope; @@ -250,6 +252,14 @@ public class PatchExtensionMethod { Binding binding = ((NameReference)methodCall.receiver).binding; if (binding instanceof TypeBinding) skip = true; } + // It's impossible to resolve the right method without types + if (Reflection.argumentsHaveErrors != null) { + try { + if ((Boolean) Reflection.argumentsHaveErrors.get(methodCall)) skip = true; + } catch (IllegalAccessException ignore) { + // ignore + } + } if (!skip) for (Extension extension : extensions) { if (!extension.suppressBaseMethods && !(methodCall.binding instanceof ProblemMethodBinding)) continue; @@ -262,13 +272,30 @@ public class PatchExtensionMethod { List<Expression> arguments = new ArrayList<Expression>(); arguments.add(methodCall.receiver); if (methodCall.arguments != null) arguments.addAll(Arrays.asList(methodCall.arguments)); + Expression[] originalArgs = methodCall.arguments; + methodCall.arguments = arguments.toArray(new Expression[0]); + List<TypeBinding> argumentTypes = new ArrayList<TypeBinding>(); for (Expression argument : arguments) { - if (argument.resolvedType != null) argumentTypes.add(argument.resolvedType); - // TODO: Instead of just skipping nulls entirely, there is probably a 'unresolved type' placeholder. THAT is what we ought to be adding here! + TypeBinding argumentType = argument.resolvedType; + if (argumentType == null && Reflection.isFunctionalExpression(argument)) { + argumentType = Reflection.getPolyTypeBinding(argument); + } + if (argumentType == null) { + argumentType = TypeBinding.NULL; + } + argumentTypes.add(argumentType); } - Expression[] originalArgs = methodCall.arguments; - methodCall.arguments = arguments.toArray(new Expression[0]); + + // Copy generic information. This one covers a few simple cases, more complex cases are still broken + int typeVariables = extensionMethod.typeVariables.length; + if (typeVariables > 0 && methodCall.receiver.resolvedType instanceof ParameterizedTypeBinding) { + ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) methodCall.receiver.resolvedType; + if (parameterizedTypeBinding.arguments != null && parameterizedTypeBinding.arguments.length == typeVariables) { + methodCall.genericTypeArguments = parameterizedTypeBinding.arguments; + } + } + MethodBinding fixedBinding = scope.getMethod(extensionMethod.declaringClass, methodCall.selector, argumentTypes.toArray(new TypeBinding[0]), methodCall); if (fixedBinding instanceof ProblemMethodBinding) { methodCall.arguments = originalArgs; @@ -276,18 +303,33 @@ public class PatchExtensionMethod { PostponedInvalidMethodError.invoke(scope.problemReporter(), methodCall, fixedBinding, scope); } } else { + // If the extension method uses varargs, the last fixed binding parameter is an array but + // the method arguments are not. Even thought we already know that the method is fine we still + // have to compare each parameter with the type of the array to support autoboxing/unboxing. + boolean isVarargs = fixedBinding.isVarargs(); for (int i = 0, iend = arguments.size(); i < iend; i++) { Expression arg = arguments.get(i); - if (fixedBinding.parameters[i].isArrayType() != arg.resolvedType.isArrayType()) break; - if (arg instanceof MessageSend) { - ((MessageSend) arg).valueCast = arg.resolvedType; + TypeBinding[] parameters = fixedBinding.parameters; + TypeBinding param; + if (isVarargs && i >= parameters.length - 1) { + // Extract the array element type for all vararg arguments + param = parameters[parameters.length - 1].leafComponentType(); + } else { + param = parameters[i]; + } + // Resolve types for lambdas + if (Reflection.isFunctionalExpression(arg)) { + arg.setExpectedType(param); + arg.resolveType(scope); } - if (!fixedBinding.parameters[i].isBaseType() && arg.resolvedType.isBaseType()) { - int id = arg.resolvedType.id; - arg.implicitConversion = TypeIds.BOXING | (id + (id << 4)); // magic see TypeIds - } else if (fixedBinding.parameters[i].isBaseType() && !arg.resolvedType.isBaseType()) { - int id = fixedBinding.parameters[i].id; - arg.implicitConversion = TypeIds.UNBOXING | (id + (id << 4)); // magic see TypeIds + if (arg.resolvedType != null) { + if (!param.isBaseType() && arg.resolvedType.isBaseType()) { + int id = arg.resolvedType.id; + arg.implicitConversion = TypeIds.BOXING | (id + (id << 4)); // magic see TypeIds + } else if (param.isBaseType() && !arg.resolvedType.isBaseType()) { + int id = parameters[i].id; + arg.implicitConversion = TypeIds.UNBOXING | (id + (id << 4)); // magic see TypeIds + } } } @@ -295,6 +337,7 @@ public class PatchExtensionMethod { methodCall.actualReceiverType = extensionMethod.declaringClass; methodCall.binding = fixedBinding; methodCall.resolvedType = methodCall.binding.returnType; + methodCall.statementEnd = methodCall.sourceEnd; if (Reflection.argumentTypes != null) { try { Reflection.argumentTypes.set(methodCall, argumentTypes.toArray(new TypeBinding[0])); @@ -340,16 +383,41 @@ public class PatchExtensionMethod { } private static final class Reflection { - public static final Field argumentTypes; + public static final Field argumentTypes = Permit.permissiveGetField(MessageSend.class, "argumentTypes"); + public static final Field argumentsHaveErrors = Permit.permissiveGetField(MessageSend.class, "argumentsHaveErrors"); + private static final Class<?> functionalExpression; + private static final Constructor<?> polyTypeBindingConstructor; static { - Field a = null; + Class<?> a = null; + Constructor<?> b = null; try { - a = Permit.getField(MessageSend.class, "argumentTypes"); - } catch (Throwable t) { - //ignore - old eclipse versions don't know this one + a = Class.forName("org.eclipse.jdt.internal.compiler.ast.FunctionalExpression"); + } catch (Exception e) { + // Ignore + } + try { + b = Permit.getConstructor(Class.forName("org.eclipse.jdt.internal.compiler.lookup.PolyTypeBinding"), Expression.class); + } catch (Exception e) { + // Ignore + } + functionalExpression = a; + polyTypeBindingConstructor = b; + } + + public static boolean isFunctionalExpression(Expression expression) { + if (functionalExpression == null) return false; + return functionalExpression.isInstance(expression); + } + + public static TypeBinding getPolyTypeBinding(Expression expression) { + if (polyTypeBindingConstructor == null) return null; + try { + return (TypeBinding) polyTypeBindingConstructor.newInstance(expression); + } catch (Exception e) { + // Ignore } - argumentTypes = a; + return null; } } } diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposal.java index 085c903f..08a42d1c 100755 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposal.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposal.java @@ -65,13 +65,14 @@ public class PatchExtensionMethodCompletionProposal { CompletionProposalCollector completionProposalCollector) { List<IJavaCompletionProposal> proposals = new ArrayList<IJavaCompletionProposal>(Arrays.asList(javaCompletionProposals)); - if (canExtendCodeAssist(proposals)) { - IJavaCompletionProposal firstProposal = proposals.get(0); - int replacementOffset = getReplacementOffset(firstProposal); + if (canExtendCodeAssist()) { for (Extension extension : getExtensionMethods(completionProposalCollector)) { for (MethodBinding method : extension.extensionMethods) { - ExtensionMethodCompletionProposal newProposal = new ExtensionMethodCompletionProposal(replacementOffset); - copyNameLookupAndCompletionEngine(completionProposalCollector, firstProposal, newProposal); + if (!isMatchingProposal(method, completionProposalCollector)) { + continue; + } + ExtensionMethodCompletionProposal newProposal = new ExtensionMethodCompletionProposal(0); + copyNameLookupAndCompletionEngine(completionProposalCollector, newProposal); ASTNode node = getAssistNode(completionProposalCollector); newProposal.setMethodBinding(method, node); createAndAddJavaCompletionProposal(completionProposalCollector, newProposal, proposals); @@ -81,7 +82,6 @@ public class PatchExtensionMethodCompletionProposal { return proposals.toArray(new IJavaCompletionProposal[0]); } - private static List<Extension> getExtensionMethods(CompletionProposalCollector completionProposalCollector) { List<Extension> extensions = new ArrayList<Extension>(); ClassScope classScope = getClassScope(completionProposalCollector); @@ -96,6 +96,17 @@ public class PatchExtensionMethodCompletionProposal { return extensions; } + private static boolean isMatchingProposal(MethodBinding method, CompletionProposalCollector completionProposalCollector) { + try { + InternalCompletionContext context = (InternalCompletionContext) Reflection.contextField.get(completionProposalCollector); + String searchToken = new String(context.getToken()); + String extensionMethodName = new String(method.selector); + return extensionMethodName.contains(searchToken); + } catch (IllegalAccessException e) { + return true; + } + } + static TypeBinding getFirstParameterType(TypeDeclaration decl, CompletionProposalCollector completionProposalCollector) { TypeBinding firstParameterType = null; ASTNode node = getAssistNode(completionProposalCollector); @@ -149,8 +160,7 @@ public class PatchExtensionMethodCompletionProposal { return scope; } - private static void copyNameLookupAndCompletionEngine(CompletionProposalCollector completionProposalCollector, IJavaCompletionProposal proposal, - InternalCompletionProposal newProposal) { + private static void copyNameLookupAndCompletionEngine(CompletionProposalCollector completionProposalCollector, InternalCompletionProposal newProposal) { try { InternalCompletionContext context = (InternalCompletionContext) Reflection.contextField.get(completionProposalCollector); @@ -173,17 +183,10 @@ public class PatchExtensionMethodCompletionProposal { } } - private static boolean canExtendCodeAssist(List<IJavaCompletionProposal> proposals) { - return !proposals.isEmpty() && Reflection.isComplete(); - } - - private static int getReplacementOffset(Object proposal) { - try { - return Reflection.replacementOffsetField.getInt(proposal); - } catch (Exception ignore) { - return 0; - } + private static boolean canExtendCodeAssist() { + return Reflection.isComplete(); } + static class Reflection { public static final Field replacementOffsetField; diff --git a/src/eclipseAgent/lombok/launch/PatchFixesHider.java b/src/eclipseAgent/lombok/launch/PatchFixesHider.java index 73a4b82d..89e2a2cc 100755 --- a/src/eclipseAgent/lombok/launch/PatchFixesHider.java +++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java @@ -39,9 +39,9 @@ import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; -import org.eclipse.jdt.core.dom.ArrayType; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.SimpleName; +import org.eclipse.jdt.core.dom.Type; import org.eclipse.jdt.core.search.SearchMatch; import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.Annotation; @@ -519,6 +519,10 @@ final class PatchFixesHider { return original == -1 ? end : original; } + public static int fixRetrieveStartBlockPosition(int original, int start) { + return original == -1 ? start : original; + } + public static int fixRetrieveRightBraceOrSemiColonPosition(int original, int end) { // if (original == -1) { // Thread.dumpStack(); @@ -540,9 +544,9 @@ final class PatchFixesHider { return -1; } - public static int fixRetrieveProperRightBracketPosition(int retVal, ArrayType arrayType) { - if (retVal != -1 || arrayType == null) return retVal; - if (isGenerated(arrayType)) return arrayType.getStartPosition() + arrayType.getLength() - 1; + public static int fixRetrieveProperRightBracketPosition(int retVal, Type type) { + if (retVal != -1 || type == null) return retVal; + if (isGenerated(type)) return type.getStartPosition() + type.getLength() - 1; return -1; } diff --git a/src/support/lombok/eclipseCreate/CreateEclipseDebugTarget.java b/src/support/lombok/eclipseCreate/CreateEclipseDebugTarget.java index e5e48c49..f54a5988 100644 --- a/src/support/lombok/eclipseCreate/CreateEclipseDebugTarget.java +++ b/src/support/lombok/eclipseCreate/CreateEclipseDebugTarget.java @@ -95,10 +95,12 @@ public class CreateEclipseDebugTarget { String bootpath = getBootPath(); - launchContent.append("\t\t<listEntry value=\"<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/lombok/bin" path="3" type="2"/> \"/>\n"); + launchContent.append("\t\t<listEntry value=\"<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/lombok/bin/main" path="3" type="2"/> \"/>\n"); for (Map.Entry<String, String> entry : args.entrySet()) { if (!entry.getKey().startsWith("conf.")) continue; - String[] files = entry.getValue().split(Pattern.quote(File.pathSeparator)); + String v = entry.getValue(); + if (v.equals("NONE")) continue; + String[] files = v.split(Pattern.quote(File.pathSeparator)); for (String file : files) { String n; try { @@ -128,7 +130,7 @@ public class CreateEclipseDebugTarget { launchContent.append("\t<listAttribute key=\"org.eclipse.jdt.launching.MODULEPATH\"/>\n"); launchContent.append("\t<stringAttribute key=\"org.eclipse.jdt.launching.PROJECT_ATTR\" value=\"lombok\"/>\n"); if (getArgBoolean("shadowLoaderBased")) { - launchContent.append("<stringAttribute key=\"org.eclipse.jdt.launching.VM_ARGUMENTS\" value=\"-javaagent:dist/lombok.jar -Dshadow.override.lombok=${project_loc:lombok}/bin"); + launchContent.append("<stringAttribute key=\"org.eclipse.jdt.launching.VM_ARGUMENTS\" value=\"-javaagent:dist/lombok.jar -Dshadow.override.lombok=${project_loc:lombok}/bin/main"); for (Map.Entry<String, String> entry : args.entrySet()) { if (!entry.getKey().startsWith("conf.")) continue; launchContent.append(File.pathSeparator).append(entry.getValue()); diff --git a/test/core/src/lombok/LombokTestSource.java b/test/core/src/lombok/LombokTestSource.java index 57a32333..a0a6407a 100644 --- a/test/core/src/lombok/LombokTestSource.java +++ b/test/core/src/lombok/LombokTestSource.java @@ -113,10 +113,10 @@ public class LombokTestSource { return formatPreferences; } - private static final Pattern VERSION_STYLE_1 = Pattern.compile("^(\\d+)$"); - private static final Pattern VERSION_STYLE_2 = Pattern.compile("^\\:(\\d+)$"); - private static final Pattern VERSION_STYLE_3 = Pattern.compile("^(\\d+):$"); - private static final Pattern VERSION_STYLE_4 = Pattern.compile("^(\\d+):(\\d+)$"); + private static final Pattern VERSION_STYLE_1 = Pattern.compile("^(\\d+)(?:\\s+.*)?$"); + private static final Pattern VERSION_STYLE_2 = Pattern.compile("^\\:(\\d+)(?:\\s+.*)?$"); + private static final Pattern VERSION_STYLE_3 = Pattern.compile("^(\\d+):(?:\\s+.*)?$"); + private static final Pattern VERSION_STYLE_4 = Pattern.compile("^(\\d+):(\\d+)(?:\\s+.*)?$"); private int[] parseVersionLimit(String spec) { /* Single version: '5' */ { diff --git a/test/core/src/lombok/RunTestsViaEcj.java b/test/core/src/lombok/RunTestsViaEcj.java index 5c29533c..b98c19b7 100644 --- a/test/core/src/lombok/RunTestsViaEcj.java +++ b/test/core/src/lombok/RunTestsViaEcj.java @@ -23,20 +23,14 @@ package lombok; import java.io.File; import java.io.StringWriter; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; -import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; import lombok.eclipse.Eclipse; import lombok.javac.CapturingDiagnosticListener.CompilerMessage; @@ -160,48 +154,13 @@ public class RunTestsViaEcj extends AbstractRunTests { Map<String, String> options = new HashMap<String, String>(); options.put(JavaCore.COMPILER_SOURCE, "11"); options.put("org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures", "enabled"); - try { - org.eclipse.jdt.internal.core.CompilationUnit ccu = new org.eclipse.jdt.internal.core.CompilationUnit(null, null, null) { - @Override public char[] getContents() { - return source; - } - }; - return AST.convertCompilationUnit(4, cud, options, false, ccu, 0, null); - } catch (SecurityException e) { - try { - debugClasspathConflicts("org/eclipse/jdt/internal/compiler"); - } catch (Exception e2) { - throw Lombok.sneakyThrow(e2); - } - throw e; - } - } - } - - @SuppressWarnings({"all"}) - private static void debugClasspathConflicts(String prefixToLookFor) throws Exception { - String[] paths = System.getProperty("java.class.path").split(":"); - for (String p : paths) { - Path cp = Paths.get(p); - if (Files.isDirectory(cp)) { - if (Files.isDirectory(cp.resolve(prefixToLookFor))) System.out.println("** DIR-BASED: " + cp); - } else if (Files.isRegularFile(cp)) { - JarFile jf = new JarFile(cp.toFile()); - try { - Enumeration<JarEntry> jes = jf.entries(); - while (jes.hasMoreElements()) { - JarEntry je = jes.nextElement(); - if (je.getName().startsWith(prefixToLookFor)) { - System.out.println("** JAR-BASED: " + cp); - break; - } - } - } finally { - jf.close(); + + org.eclipse.jdt.internal.core.CompilationUnit ccu = new org.eclipse.jdt.internal.core.CompilationUnit(null, null, null) { + @Override public char[] getContents() { + return source; } - } else { - System.out.println("** MISSING: " + cp); - } + }; + return AST.convertCompilationUnit(4, cud, options, false, ccu, 0, null); } } diff --git a/test/pretty/resource/before/ThisParameter.java b/test/pretty/resource/before/ThisParameter.java index d95c0261..e37651cb 100644 --- a/test/pretty/resource/before/ThisParameter.java +++ b/test/pretty/resource/before/ThisParameter.java @@ -1,3 +1,4 @@ +// version 9: the 'this' param option exists in java8, but is bugged, in that annotations are not allowed on them, even without a @Target. The only purpose of the this param is annotations, so, boy, isn't that a punch in the face? import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/transform/resource/after-delombok/ExtensionMethodAutoboxing.java b/test/transform/resource/after-delombok/ExtensionMethodAutoboxing.java new file mode 100644 index 00000000..f274cabb --- /dev/null +++ b/test/transform/resource/after-delombok/ExtensionMethodAutoboxing.java @@ -0,0 +1,20 @@ +class ExtensionMethodAutoboxing { + public void test() { + Long l1 = 1L; + long l2 = 1L; + Integer i1 = 1; + int i2 = 1; + String string = "test"; + ExtensionMethodAutoboxing.Extensions.boxing(string, l1, i1); + ExtensionMethodAutoboxing.Extensions.boxing(string, l1, i2); + ExtensionMethodAutoboxing.Extensions.boxing(string, l2, i1); + ExtensionMethodAutoboxing.Extensions.boxing(string, l2, i2); + } + + + static class Extensions { + public static String boxing(String string, Long a, int b) { + return string + " " + a + " " + b; + } + } +}
\ No newline at end of file diff --git a/test/transform/resource/after-delombok/ExtensionMethodFunctional.java b/test/transform/resource/after-delombok/ExtensionMethodFunctional.java new file mode 100644 index 00000000..bd301543 --- /dev/null +++ b/test/transform/resource/after-delombok/ExtensionMethodFunctional.java @@ -0,0 +1,28 @@ +import java.util.function.Function; +import java.util.function.Consumer; + +class ExtensionMethodFunctional { + public void test() { + String test = "test"; + test = ExtensionMethodFunctional.Extensions.map(test, s -> ExtensionMethodFunctional.Extensions.reverse(s)); + ExtensionMethodFunctional.Extensions.consume(test, s -> System.out.println("1: " + s), s -> System.out.println("2: " + s)); + ExtensionMethodFunctional.Extensions.consume(test, System.out::println, System.out::println); + } + + static class Extensions { + public static <T, R> R map(T value, Function<T, R> mapper) { + return mapper.apply(value); + } + + public static String reverse(String string) { + return new StringBuilder(string).reverse().toString(); + } + + @SafeVarargs + public static <T> void consume(T o, Consumer<T>... consumer) { + for (int i = 0; i < consumer.length; i++) { + consumer[i].accept(o); + } + } + } +} diff --git a/test/transform/resource/after-delombok/ExtensionMethodVarargs.java b/test/transform/resource/after-delombok/ExtensionMethodVarargs.java new file mode 100644 index 00000000..237b73ef --- /dev/null +++ b/test/transform/resource/after-delombok/ExtensionMethodVarargs.java @@ -0,0 +1,19 @@ +class ExtensionMethodVarargs { + public void test() { + Long l1 = 1L; + long l2 = 1L; + Integer i1 = 1; + int i2 = 1; + ExtensionMethodVarargs.Extensions.format("%d %d %d %d", l1, l2, i1, i2); + ExtensionMethodVarargs.Extensions.format("%d", l1); + ExtensionMethodVarargs.Extensions.format("", new Integer[] {1, 2}); + ExtensionMethodVarargs.Extensions.format("", new Integer[] {1, 2}, new Integer[] {1, 2}); + } + + + static class Extensions { + public static String format(String string, Object... params) { + return String.format(string, params); + } + } +}
\ No newline at end of file diff --git a/test/transform/resource/after-delombok/LoggerSlf4j.java b/test/transform/resource/after-delombok/LoggerSlf4j.java index 70f11ae4..152c8708 100644 --- a/test/transform/resource/after-delombok/LoggerSlf4j.java +++ b/test/transform/resource/after-delombok/LoggerSlf4j.java @@ -29,8 +29,3 @@ class LoggerSlf4jWithTwoStaticFields { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4jWithTwoStaticFields.TOPIC + LoggerSlf4jWithTwoStaticFields.TOPIC); static final String TOPIC = "StaticField"; } - -class LoggerSlf4jWithTwoLiterals { - @java.lang.SuppressWarnings("all") - private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger("A" + "B"); -}
\ No newline at end of file diff --git a/test/transform/resource/after-ecj/ExtensionMethodAutoboxing.java b/test/transform/resource/after-ecj/ExtensionMethodAutoboxing.java new file mode 100644 index 00000000..8bc2b30f --- /dev/null +++ b/test/transform/resource/after-ecj/ExtensionMethodAutoboxing.java @@ -0,0 +1,25 @@ +import lombok.experimental.ExtensionMethod; +@ExtensionMethod({ExtensionMethodAutoboxing.Extensions.class}) class ExtensionMethodAutoboxing { + static class Extensions { + Extensions() { + super(); + } + public static String boxing(String string, Long a, int b) { + return ((((string + " ") + a) + " ") + b); + } + } + ExtensionMethodAutoboxing() { + super(); + } + public void test() { + Long l1 = 1l; + long l2 = 1l; + Integer i1 = 1; + int i2 = 1; + String string = "test"; + ExtensionMethodAutoboxing.Extensions.boxing(string, l1, i1); + ExtensionMethodAutoboxing.Extensions.boxing(string, l1, i2); + ExtensionMethodAutoboxing.Extensions.boxing(string, l2, i1); + ExtensionMethodAutoboxing.Extensions.boxing(string, l2, i2); + } +}
\ No newline at end of file diff --git a/test/transform/resource/after-ecj/ExtensionMethodFunctional.java b/test/transform/resource/after-ecj/ExtensionMethodFunctional.java new file mode 100644 index 00000000..0190eabb --- /dev/null +++ b/test/transform/resource/after-ecj/ExtensionMethodFunctional.java @@ -0,0 +1,31 @@ +import java.util.function.Function; +import java.util.function.Consumer; +import lombok.experimental.ExtensionMethod; +@ExtensionMethod(ExtensionMethodFunctional.Extensions.class) class ExtensionMethodFunctional { + static class Extensions { + Extensions() { + super(); + } + public static <T, R>R map(T value, Function<T, R> mapper) { + return mapper.apply(value); + } + public static String reverse(String string) { + return new StringBuilder(string).reverse().toString(); + } + public static @SafeVarargs <T>void consume(T o, Consumer<T>... consumer) { + for (int i = 0;; (i < consumer.length); i ++) + { + consumer[i].accept(o); + } + } + } + ExtensionMethodFunctional() { + super(); + } + public void test() { + String test = "test"; + test = ExtensionMethodFunctional.Extensions.map(test, (<no type> s) -> ExtensionMethodFunctional.Extensions.reverse(s)); + ExtensionMethodFunctional.Extensions.consume(test, (<no type> s) -> System.out.println(("1: " + s)), (<no type> s) -> System.out.println(("2: " + s))); + ExtensionMethodFunctional.Extensions.consume(test, System.out::println, System.out::println); + } +} diff --git a/test/transform/resource/after-ecj/ExtensionMethodVarargs.java b/test/transform/resource/after-ecj/ExtensionMethodVarargs.java new file mode 100644 index 00000000..727b6494 --- /dev/null +++ b/test/transform/resource/after-ecj/ExtensionMethodVarargs.java @@ -0,0 +1,24 @@ +import lombok.experimental.ExtensionMethod; +@ExtensionMethod(ExtensionMethodVarargs.Extensions.class) class ExtensionMethodVarargs { + static class Extensions { + Extensions() { + super(); + } + public static String format(String string, Object... params) { + return String.format(string, params); + } + } + ExtensionMethodVarargs() { + super(); + } + public void test() { + Long l1 = 1l; + long l2 = 1l; + Integer i1 = 1; + int i2 = 1; + ExtensionMethodVarargs.Extensions.format("%d %d %d %d", l1, l2, i1, i2); + ExtensionMethodVarargs.Extensions.format("%d", l1); + ExtensionMethodVarargs.Extensions.format("", new Integer[]{1, 2}); + ExtensionMethodVarargs.Extensions.format("", new Integer[]{1, 2}, new Integer[]{1, 2}); + } +}
\ No newline at end of file diff --git a/test/transform/resource/after-ecj/LoggerSlf4j.java b/test/transform/resource/after-ecj/LoggerSlf4j.java index c303a895..286d023b 100644 --- a/test/transform/resource/after-ecj/LoggerSlf4j.java +++ b/test/transform/resource/after-ecj/LoggerSlf4j.java @@ -56,11 +56,3 @@ class LoggerSlf4jOuter { super(); } } -@Slf4j(topic = ExtendedStringLiteral{AB}) class LoggerSlf4jWithTwoLiterals { - private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger("AB"); - <clinit>() { - } - LoggerSlf4jWithTwoLiterals() { - super(); - } -}
\ No newline at end of file diff --git a/test/transform/resource/before/ExtensionMethodAutoboxing.java b/test/transform/resource/before/ExtensionMethodAutoboxing.java new file mode 100644 index 00000000..5e07a6b3 --- /dev/null +++ b/test/transform/resource/before/ExtensionMethodAutoboxing.java @@ -0,0 +1,23 @@ +import lombok.experimental.ExtensionMethod; + +@ExtensionMethod({ExtensionMethodAutoboxing.Extensions.class}) +class ExtensionMethodAutoboxing { + public void test() { + Long l1 = 1l; + long l2 = 1l; + Integer i1 = 1; + int i2 = 1; + + String string = "test"; + string.boxing(l1, i1); + string.boxing(l1, i2); + string.boxing(l2, i1); + string.boxing(l2, i2); + } + + static class Extensions { + public static String boxing(String string, Long a, int b) { + return string + " " + a + " " + b; + } + } +} diff --git a/test/transform/resource/before/ExtensionMethodFunctional.java b/test/transform/resource/before/ExtensionMethodFunctional.java new file mode 100644 index 00000000..19983258 --- /dev/null +++ b/test/transform/resource/before/ExtensionMethodFunctional.java @@ -0,0 +1,33 @@ +// version 8: +import java.util.function.Function; +import java.util.function.Consumer; + +import lombok.experimental.ExtensionMethod; + +@ExtensionMethod(ExtensionMethodFunctional.Extensions.class) +class ExtensionMethodFunctional { + public void test() { + String test = "test"; + test = test.map(s -> s.reverse()); + + test.consume(s -> System.out.println("1: " + s), s -> System.out.println("2: " + s)); + test.consume(System.out::println, System.out::println); + } + + static class Extensions { + public static <T, R> R map(T value, Function<T, R> mapper) { + return mapper.apply(value); + } + + public static String reverse(String string) { + return new StringBuilder(string).reverse().toString(); + } + + @SafeVarargs + public static <T> void consume(T o, Consumer<T>... consumer) { + for (int i = 0; i < consumer.length; i++) { + consumer[i].accept(o); + } + } + } +} diff --git a/test/transform/resource/before/ExtensionMethodVarargs.java b/test/transform/resource/before/ExtensionMethodVarargs.java new file mode 100644 index 00000000..a976f9e6 --- /dev/null +++ b/test/transform/resource/before/ExtensionMethodVarargs.java @@ -0,0 +1,23 @@ +// version 8: +import lombok.experimental.ExtensionMethod; + +@ExtensionMethod(ExtensionMethodVarargs.Extensions.class) +class ExtensionMethodVarargs { + public void test() { + Long l1 = 1l; + long l2 = 1l; + Integer i1 = 1; + int i2 = 1; + + "%d %d %d %d".format(l1, l2, i1, i2); + "%d".format(l1); + "".format(new Integer[]{1,2}); + "".format(new Integer[]{1,2}, new Integer[]{1,2}); + } + + static class Extensions { + public static String format(String string, Object... params) { + return String.format(string, params); + } + } +} diff --git a/test/transform/resource/before/LoggerSlf4j.java b/test/transform/resource/before/LoggerSlf4j.java index 3f8284e8..c59db4ee 100644 --- a/test/transform/resource/before/LoggerSlf4j.java +++ b/test/transform/resource/before/LoggerSlf4j.java @@ -28,7 +28,3 @@ class LoggerSlf4jWithStaticField { class LoggerSlf4jWithTwoStaticFields { static final String TOPIC = "StaticField"; } - -@Slf4j(topic="A"+"B") -class LoggerSlf4jWithTwoLiterals { -}
\ No newline at end of file diff --git a/test/transform/resource/messages-delombok/ExtensionMethodVarargs.java.messages b/test/transform/resource/messages-delombok/ExtensionMethodVarargs.java.messages new file mode 100644 index 00000000..587d0767 --- /dev/null +++ b/test/transform/resource/messages-delombok/ExtensionMethodVarargs.java.messages @@ -0,0 +1 @@ +14 non-varargs call of varargs method with inexact argument type for last parameter
\ No newline at end of file diff --git a/test/transform/resource/messages-idempotent/ExtensionMethodVarargs.java.messages b/test/transform/resource/messages-idempotent/ExtensionMethodVarargs.java.messages new file mode 100644 index 00000000..5a1016ca --- /dev/null +++ b/test/transform/resource/messages-idempotent/ExtensionMethodVarargs.java.messages @@ -0,0 +1 @@ +9 non-varargs call of varargs method with inexact argument type for last parameter
\ No newline at end of file |