diff options
Diffstat (limited to 'src/core/lombok/eclipse/Eclipse.java')
-rw-r--r-- | src/core/lombok/eclipse/Eclipse.java | 140 |
1 files changed, 139 insertions, 1 deletions
diff --git a/src/core/lombok/eclipse/Eclipse.java b/src/core/lombok/eclipse/Eclipse.java index 659651d6..c4632fba 100644 --- a/src/core/lombok/eclipse/Eclipse.java +++ b/src/core/lombok/eclipse/Eclipse.java @@ -25,6 +25,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -63,7 +64,13 @@ import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.TypeParameter; import org.eclipse.jdt.internal.compiler.ast.TypeReference; import org.eclipse.jdt.internal.compiler.ast.Wildcard; +import org.eclipse.jdt.internal.compiler.lookup.CaptureBinding; +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 org.eclipse.jdt.internal.compiler.lookup.WildcardBinding; import org.osgi.framework.Bundle; public class Eclipse { @@ -157,7 +164,6 @@ public class Eclipse { return result; } - /** * You can't share TypeParameter objects or bad things happen; for example, one 'T' resolves differently * from another 'T', even for the same T in a single class file. Unfortunately the TypeParameter type hierarchy @@ -293,6 +299,138 @@ public class Eclipse { return ref; } + private static long pos(ASTNode node) { + return ((long) node.sourceStart << 32) | (node.sourceEnd & 0xFFFFFFFFL); + } + + public static long[] poss(ASTNode node, int repeat) { + long p = ((long) node.sourceStart << 32) | (node.sourceEnd & 0xFFFFFFFFL); + long[] out = new long[repeat]; + Arrays.fill(out, p); + return out; + } + + public static TypeReference makeType(TypeBinding binding, ASTNode pos, boolean allowCompound) { + // Primitives + switch (binding.id) { + case TypeIds.T_int: + return new SingleTypeReference(TypeConstants.INT, pos(pos)); + case TypeIds.T_long: + return new SingleTypeReference(TypeConstants.LONG, pos(pos)); + case TypeIds.T_short: + return new SingleTypeReference(TypeConstants.SHORT, pos(pos)); + case TypeIds.T_byte: + return new SingleTypeReference(TypeConstants.BYTE, pos(pos)); + case TypeIds.T_double: + return new SingleTypeReference(TypeConstants.DOUBLE, pos(pos)); + case TypeIds.T_float: + return new SingleTypeReference(TypeConstants.FLOAT, pos(pos)); + case TypeIds.T_boolean: + return new SingleTypeReference(TypeConstants.BOOLEAN, pos(pos)); + case TypeIds.T_void: + return new SingleTypeReference(TypeConstants.VOID, pos(pos)); + case TypeIds.T_char: + return new SingleTypeReference(TypeConstants.CHAR, pos(pos)); + case TypeIds.T_null: + return null; + } + + if (binding.isAnonymousType()) { + ReferenceBinding ref = (ReferenceBinding)binding; + ReferenceBinding[] supers = ref.superInterfaces(); + if (supers == null || supers.length == 0) supers = new ReferenceBinding[] {ref.superclass()}; + if (supers[0] == null) return new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(pos, 3)); + return makeType(supers[0], pos, false); + } + + if (binding instanceof CaptureBinding) { + return makeType(((CaptureBinding)binding).wildcard, pos, allowCompound); + } + + if (binding.isUnboundWildcard()) { + if (!allowCompound) { + return new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(pos, 3)); + } else { + Wildcard out = new Wildcard(Wildcard.UNBOUND); + out.sourceStart = pos.sourceStart; + out.sourceEnd = pos.sourceEnd; + return out; + } + } + + if (binding.isWildcard()) { + WildcardBinding wildcard = (WildcardBinding) binding; + if (wildcard.boundKind == Wildcard.EXTENDS) { + if (!allowCompound) { + return makeType(wildcard.bound, pos, false); + } else { + Wildcard out = new Wildcard(Wildcard.EXTENDS); + out.bound = makeType(wildcard.bound, pos, false); + out.sourceStart = pos.sourceStart; + out.sourceEnd = pos.sourceEnd; + return out; + } + } else if (allowCompound && wildcard.boundKind == Wildcard.SUPER) { + Wildcard out = new Wildcard(Wildcard.SUPER); + out.bound = makeType(wildcard.bound, pos, false); + out.sourceStart = pos.sourceStart; + out.sourceEnd = pos.sourceEnd; + return out; + } else { + return new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(pos, 3)); + } + } + + char[][] parts; + + if (binding.isLocalType() || binding.isTypeVariable()) { + parts = new char[][] { binding.shortReadableName() }; + } else { + String[] pkg = new String(binding.qualifiedPackageName()).split("\\."); + String[] name = new String(binding.qualifiedSourceName()).split("\\."); + parts = new char[pkg.length + name.length][]; + int ptr; + for (ptr = 0; ptr < pkg.length; ptr++) parts[ptr] = pkg[ptr].toCharArray(); + for (; ptr < pkg.length + name.length; ptr++) parts[ptr] = name[ptr - pkg.length].toCharArray(); + } + + TypeReference[] params = new TypeReference[0]; + + if (binding instanceof ParameterizedTypeBinding) { + ParameterizedTypeBinding paramized = (ParameterizedTypeBinding) binding; + if (paramized.arguments != null) { + params = new TypeReference[paramized.arguments.length]; + for (int i = 0; i < params.length; i++) { + params[i] = makeType(paramized.arguments[i], pos, true); + } + } + } + + int dims = binding.dimensions(); + + if (params.length > 0) { + if (parts.length > 1) { + TypeReference[][] typeArguments = new TypeReference[parts.length][]; + typeArguments[typeArguments.length - 1] = params; + return new ParameterizedQualifiedTypeReference(parts, typeArguments, dims, poss(pos, parts.length)); + } + return new ParameterizedSingleTypeReference(parts[0], params, dims, pos(pos)); + } + + if (dims > 0) { + if (parts.length > 1) { + return new ArrayQualifiedTypeReference(parts, dims, poss(pos, parts.length)); + } + return new ArrayTypeReference(parts[0], dims, pos(pos)); + } + + if (parts.length > 1) { + return new QualifiedTypeReference(parts, poss(pos, parts.length)); + } + return new SingleTypeReference(parts[0], pos(pos)); + + } + public static Annotation[] copyAnnotations(Annotation[] annotations, ASTNode source) { return copyAnnotations(annotations, null, source); } |