aboutsummaryrefslogtreecommitdiff
path: root/src/eclipseAgent/lombok
diff options
context:
space:
mode:
Diffstat (limited to 'src/eclipseAgent/lombok')
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchVal.java71
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java8
2 files changed, 49 insertions, 30 deletions
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
index 43e93bbe..e4dd7b26 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
@@ -21,9 +21,22 @@
*/
package lombok.eclipse.agent;
-import org.eclipse.jdt.internal.compiler.ast.*;
+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.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.lookup.*;
+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.ParameterizedTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import java.lang.reflect.Field;
@@ -31,13 +44,13 @@ import static lombok.eclipse.Eclipse.poss;
import static lombok.eclipse.handlers.EclipseHandlerUtil.makeType;
public class PatchVal {
-
+
// This is half of the work for 'val' support - the other half is in PatchValEclipse. This half is enough for ecj.
// Creates a copy of the 'initialization' field on a LocalDeclaration if the type of the LocalDeclaration is 'val', because the completion parser will null this out,
// which in turn stops us from inferring the intended type for 'val x = 5;'. We look at the copy.
// Also patches local declaration to not call .resolveType() on the initializer expression if we've already done so (calling it twice causes weird errors),
// and patches .resolve() on LocalDeclaration itself to just-in-time replace the 'val' vartype with the right one.
-
+
public static TypeBinding skipResolveInitializerIfAlreadyCalled(Expression expr, BlockScope scope) {
if (expr.resolvedType != null) return expr.resolvedType;
try {
@@ -49,7 +62,7 @@ public class PatchVal {
return null;
}
}
-
+
public static TypeBinding skipResolveInitializerIfAlreadyCalled2(Expression expr, BlockScope scope, LocalDeclaration decl) {
if (decl != null && LocalDeclaration.class.equals(decl.getClass()) && expr.resolvedType != null) return expr.resolvedType;
try {
@@ -61,23 +74,23 @@ public class PatchVal {
return null;
}
}
-
+
public static boolean matches(String key, char[] array) {
if (array == null || key.length() != array.length) return false;
for (int i = 0; i < array.length; i++) {
if (key.charAt(i) != array[i]) return false;
}
-
+
return true;
}
-
+
public static boolean couldBe(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 (ref instanceof QualifiedTypeReference) {
char[][] tokens = ((QualifiedTypeReference)ref).tokens;
if (keyParts.length != tokens.length) return false;
@@ -88,7 +101,7 @@ public class PatchVal {
}
return true;
}
-
+
return false;
}
@@ -110,20 +123,20 @@ public class PatchVal {
System.arraycopy(nm, 0, fullName, pkgFullLength, nm.length);
return matches(key, fullName);
}
-
+
public static final class Reflection {
private static final Field initCopyField, iterableCopyField;
-
+
static {
Field a = null, b = null;
-
+
try {
a = LocalDeclaration.class.getDeclaredField("$initCopy");
b = LocalDeclaration.class.getDeclaredField("$iterableCopy");
} catch (Throwable t) {
//ignore - no $initCopy exists when running in ecj.
}
-
+
initCopyField = a;
iterableCopyField = b;
}
@@ -131,11 +144,11 @@ public class PatchVal {
public static boolean handleValForLocalDeclaration(LocalDeclaration local, BlockScope scope) {
if (local == null || !LocalDeclaration.class.equals(local.getClass())) return false;
boolean decomponent = false;
-
+
boolean val = isVal(local, scope);
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")) {
@@ -146,7 +159,7 @@ public class PatchVal {
break;
}
}
-
+
Expression init = local.initialization;
if (init == null && Reflection.initCopyField != null) {
try {
@@ -155,7 +168,7 @@ public class PatchVal {
// init remains null.
}
}
-
+
if (init == null && Reflection.iterableCopyField != null) {
try {
init = (Expression) Reflection.iterableCopyField.get(local);
@@ -190,7 +203,7 @@ public class PatchVal {
}
}
}
-
+
if(val) local.modifiers |= ClassFileConstants.AccFinal;
local.annotations = addValAnnotation(local.annotations, local.type, scope);
local.type = replacement != null ? replacement : new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(local.type, 3));
@@ -212,16 +225,16 @@ public class PatchVal {
boolean val = isVal(forEach.elementVariable, scope);
boolean var = isVar(forEach.elementVariable, scope);
if (!(val || var)) return false;
-
+
TypeBinding component = getForEachComponentType(forEach.collection, scope);
if (component == null) return false;
TypeReference replacement = makeType(component, forEach.elementVariable.type, false);
-
+
if (val) forEach.elementVariable.modifiers |= ClassFileConstants.AccFinal;
forEach.elementVariable.annotations = addValAnnotation(forEach.elementVariable.annotations, forEach.elementVariable.type, scope);
forEach.elementVariable.type = replacement != null ? replacement :
new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(forEach.elementVariable.type, 3));
-
+
return false;
}
@@ -233,12 +246,12 @@ public class PatchVal {
} else {
newAnn = new Annotation[1];
}
-
+
newAnn[newAnn.length - 1] = new org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation(originalRef, originalRef.sourceStart);
-
+
return newAnn;
}
-
+
private static TypeBinding getForEachComponentType(Expression collection, BlockScope scope) {
if (collection != null) {
TypeBinding resolved = collection.resolvedType;
@@ -249,7 +262,7 @@ public class PatchVal {
return resolved;
} else if (resolved instanceof ReferenceBinding) {
ReferenceBinding iterableType = ((ReferenceBinding)resolved).findSuperTypeOriginatingFrom(TypeIds.T_JavaLangIterable, false);
-
+
TypeBinding[] arguments = null;
if (iterableType != null) switch (iterableType.kind()) {
case Binding.GENERIC_TYPE : // for (T t : Iterable<T>) - in case used inside Iterable itself
@@ -261,16 +274,16 @@ public class PatchVal {
case Binding.RAW_TYPE : // for(Object e : Iterable)
return null;
}
-
+
if (arguments != null && arguments.length == 1) {
return arguments[0];
}
}
}
-
+
return null;
}
-
+
private static TypeBinding resolveForExpression(Expression collection, BlockScope scope) {
try {
return collection.resolveType(scope);
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java b/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java
index d0c29ac8..505eb767 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java
@@ -41,7 +41,13 @@ import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
-import org.eclipse.jdt.internal.compiler.ast.*;
+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.LocalDeclaration;
+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;