use of org.eclipse.jdt.internal.compiler.lookup.BlockScope in project lombok by rzwitserloot.
the class PatchExtensionMethod method getApplicableExtensionMethods.
static List<Extension> getApplicableExtensionMethods(EclipseNode typeNode, Annotation ann, TypeBinding receiverType) {
List<Extension> extensions = new ArrayList<Extension>();
if ((typeNode != null) && (ann != null) && (receiverType != null)) {
BlockScope blockScope = ((TypeDeclaration) typeNode.get()).initializerScope;
EclipseNode annotationNode = typeNode.getNodeFor(ann);
AnnotationValues<ExtensionMethod> annotation = createAnnotation(ExtensionMethod.class, annotationNode);
boolean suppressBaseMethods = false;
try {
suppressBaseMethods = annotation.getInstance().suppressBaseMethods();
} catch (AnnotationValueDecodeFail fail) {
fail.owner.setError(fail.getMessage(), fail.idx);
}
for (Object extensionMethodProvider : annotation.getActualExpressions("value")) {
if (extensionMethodProvider instanceof ClassLiteralAccess) {
TypeBinding binding = ((ClassLiteralAccess) extensionMethodProvider).type.resolveType(blockScope);
if (binding == null)
continue;
if (!binding.isClass() && !binding.isEnum())
continue;
Extension e = new Extension();
e.extensionMethods = getApplicableExtensionMethodsDefinedInProvider(typeNode, (ReferenceBinding) binding, receiverType);
e.suppressBaseMethods = suppressBaseMethods;
extensions.add(e);
}
}
}
return extensions;
}
use of org.eclipse.jdt.internal.compiler.lookup.BlockScope in project spoon by INRIA.
the class ReferenceBuilder method buildTypeReferenceInternal.
private <T> CtTypeReference<T> buildTypeReferenceInternal(CtTypeReference<T> typeReference, TypeReference type, Scope scope) {
if (type == null) {
return null;
}
CtTypeReference<?> currentReference = typeReference;
for (int position = type.getTypeName().length - 1; position >= 0; position--) {
if (currentReference == null) {
break;
}
this.jdtTreeBuilder.getContextBuilder().enter(currentReference, type);
if (type.annotations != null && type.annotations.length - 1 <= position && type.annotations[position] != null && type.annotations[position].length > 0) {
for (Annotation annotation : type.annotations[position]) {
if (scope instanceof ClassScope) {
annotation.traverse(this.jdtTreeBuilder, (ClassScope) scope);
} else if (scope instanceof BlockScope) {
annotation.traverse(this.jdtTreeBuilder, (BlockScope) scope);
} else {
annotation.traverse(this.jdtTreeBuilder, (BlockScope) null);
}
}
}
if (type.getTypeArguments() != null && type.getTypeArguments().length - 1 <= position && type.getTypeArguments()[position] != null && type.getTypeArguments()[position].length > 0) {
currentReference.getActualTypeArguments().clear();
for (TypeReference typeArgument : type.getTypeArguments()[position]) {
if (typeArgument instanceof Wildcard || typeArgument.resolvedType instanceof WildcardBinding || typeArgument.resolvedType instanceof TypeVariableBinding) {
currentReference.addActualTypeArgument(buildTypeParameterReference(typeArgument, scope));
} else {
currentReference.addActualTypeArgument(buildTypeReference(typeArgument, scope));
}
}
} else if ((type instanceof ParameterizedSingleTypeReference || type instanceof ParameterizedQualifiedTypeReference) && !isTypeArgumentExplicit(type.getTypeArguments())) {
for (CtTypeReference<?> actualTypeArgument : currentReference.getActualTypeArguments()) {
actualTypeArgument.setImplicit(true);
if (actualTypeArgument instanceof CtArrayTypeReference) {
((CtArrayTypeReference) actualTypeArgument).getComponentType().setImplicit(true);
}
}
}
if (type instanceof Wildcard && typeReference instanceof CtTypeParameterReference) {
((CtTypeParameterReference) typeReference).setBoundingType(buildTypeReference(((Wildcard) type).bound, scope));
}
this.jdtTreeBuilder.getContextBuilder().exit(type);
currentReference = currentReference.getDeclaringType();
}
return typeReference;
}
use of org.eclipse.jdt.internal.compiler.lookup.BlockScope in project lombok by rzwitserloot.
the class HandleHelper method handle.
@Override
public void handle(AnnotationValues<Helper> annotation, Annotation ast, EclipseNode annotationNode) {
handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.HELPER_FLAG_USAGE, "@Helper");
EclipseNode annotatedType = annotationNode.up();
EclipseNode containingBlock = annotatedType == null ? null : annotatedType.directUp();
Statement[] origStatements = getStatementsFromAstNode(containingBlock == null ? null : containingBlock.get());
if (annotatedType == null || annotatedType.getKind() != Kind.TYPE || origStatements == null) {
annotationNode.addError("@Helper is legal only on method-local classes.");
return;
}
TypeDeclaration annotatedType_ = (TypeDeclaration) annotatedType.get();
int indexOfType = -1;
for (int i = 0; i < origStatements.length; i++) {
if (origStatements[i] == annotatedType_) {
indexOfType = i;
break;
}
}
final List<String> knownMethodNames = new ArrayList<String>();
for (AbstractMethodDeclaration methodOfHelper : annotatedType_.methods) {
if (!(methodOfHelper instanceof MethodDeclaration))
continue;
char[] name = methodOfHelper.selector;
if (name != null && name.length > 0 && name[0] != '<')
knownMethodNames.add(new String(name));
}
Collections.sort(knownMethodNames);
final String[] knownMethodNames_ = knownMethodNames.toArray(new String[knownMethodNames.size()]);
final char[] helperName = new char[annotatedType_.name.length + 1];
final boolean[] helperUsed = new boolean[1];
helperName[0] = '$';
System.arraycopy(annotatedType_.name, 0, helperName, 1, helperName.length - 1);
ASTVisitor visitor = new ASTVisitor() {
@Override
public boolean visit(MessageSend messageSend, BlockScope scope) {
if (messageSend.receiver instanceof ThisReference) {
if ((((ThisReference) messageSend.receiver).bits & ASTNode.IsImplicitThis) == 0)
return true;
} else if (messageSend.receiver != null)
return true;
char[] name = messageSend.selector;
if (name == null || name.length == 0 || name[0] == '<')
return true;
String n = new String(name);
if (Arrays.binarySearch(knownMethodNames_, n) < 0)
return true;
messageSend.receiver = new SingleNameReference(helperName, messageSend.nameSourcePosition);
helperUsed[0] = true;
return true;
}
};
for (int i = indexOfType + 1; i < origStatements.length; i++) {
origStatements[i].traverse(visitor, null);
}
if (!helperUsed[0]) {
annotationNode.addWarning("No methods of this helper class are ever used.");
return;
}
Statement[] newStatements = new Statement[origStatements.length + 1];
System.arraycopy(origStatements, 0, newStatements, 0, indexOfType + 1);
System.arraycopy(origStatements, indexOfType + 1, newStatements, indexOfType + 2, origStatements.length - indexOfType - 1);
LocalDeclaration decl = new LocalDeclaration(helperName, 0, 0);
decl.modifiers |= ClassFileConstants.AccFinal;
AllocationExpression alloc = new AllocationExpression();
alloc.type = new SingleTypeReference(annotatedType_.name, 0L);
decl.initialization = alloc;
decl.type = new SingleTypeReference(annotatedType_.name, 0L);
SetGeneratedByVisitor sgbvVisitor = new SetGeneratedByVisitor(annotationNode.get());
decl.traverse(sgbvVisitor, null);
newStatements[indexOfType + 1] = decl;
setStatementsOfAstNode(containingBlock.get(), newStatements);
}
Aggregations