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; }
@Override public Expression createFactoryParameter(ClassLiteralAccess type, Annotation source) { int pS = source.sourceStart, pE = source.sourceEnd; long p = (long)pS << 32 | pE; MessageSend factoryParameterCall = new MessageSend(); setGeneratedBy(factoryParameterCall, source); factoryParameterCall.receiver = super.createFactoryParameter(type, source); factoryParameterCall.selector = "getName".toCharArray(); factoryParameterCall.nameSourcePosition = p; factoryParameterCall.sourceStart = pS; factoryParameterCall.sourceEnd = factoryParameterCall.statementEnd = pE; return factoryParameterCall; }
/** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(ClassLiteralAccess classLiteral, BlockScope scope) { final int numberOfParens = (classLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(classLiteral, numberOfParens); } classLiteral.type.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameDOT); this.scribe.printNextToken(TerminalTokens.TokenNameclass); if (numberOfParens > 0) { manageClosingParenthesizedExpression(classLiteral, numberOfParens); } return false; }
/** * Returns the actual value of the given Literal or Literal-like node. */ public static Object calculateValue(Expression e) { if (e instanceof Literal) { ((Literal)e).computeConstant(); switch (e.constant.typeID()) { case TypeIds.T_int: return e.constant.intValue(); case TypeIds.T_byte: return e.constant.byteValue(); case TypeIds.T_short: return e.constant.shortValue(); case TypeIds.T_char: return e.constant.charValue(); case TypeIds.T_float: return e.constant.floatValue(); case TypeIds.T_double: return e.constant.doubleValue(); case TypeIds.T_boolean: return e.constant.booleanValue(); case TypeIds.T_long: return e.constant.longValue(); case TypeIds.T_JavaLangString: return e.constant.stringValue(); default: return null; } } else if (e instanceof ClassLiteralAccess) { return Eclipse.toQualifiedName(((ClassLiteralAccess)e).type.getTypeName()); } else if (e instanceof SingleNameReference) { return new String(((SingleNameReference)e).token); } else if (e instanceof QualifiedNameReference) { String qName = Eclipse.toQualifiedName(((QualifiedNameReference)e).tokens); int idx = qName.lastIndexOf('.'); return idx == -1 ? qName : qName.substring(idx+1); } return null; }
public static ClassLiteralAccess selfType(EclipseNode type, Annotation source) { int pS = source.sourceStart, pE = source.sourceEnd; long p = (long)pS << 32 | pE; TypeDeclaration typeDeclaration = (TypeDeclaration)type.get(); TypeReference typeReference = new SingleTypeReference(typeDeclaration.name, p); setGeneratedBy(typeReference, source); ClassLiteralAccess result = new ClassLiteralAccess(source.sourceEnd, typeReference); setGeneratedBy(result, source); return result; }
protected void consumePrimaryNoNewArrayArrayType() { // PrimaryNoNewArray ::= Name Dims '.' 'class' this.intPtr--; // remove the class start position pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]); pushOnGenericsLengthStack(0); ClassLiteralAccess cla; pushOnExpressionStack( cla = new ClassLiteralAccess(this.intStack[this.intPtr--], getTypeReference(this.intStack[this.intPtr--]))); rejectIllegalTypeAnnotations(cla.type); // javac correctly rejects annotations on dimensions here. }
protected void consumePrimaryNoNewArrayName() { // PrimaryNoNewArray ::= Name '.' 'class' this.intPtr--; // remove the class start position // handle type arguments pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]); pushOnGenericsLengthStack(0); TypeReference typeReference = getTypeReference(0); rejectIllegalTypeAnnotations(typeReference); pushOnExpressionStack( new ClassLiteralAccess(this.intStack[this.intPtr--], typeReference)); }
protected void consumePrimaryNoNewArrayPrimitiveArrayType() { // PrimaryNoNewArray ::= PrimitiveType Dims '.' 'class' this.intPtr--; // remove the class start position ClassLiteralAccess cla; pushOnExpressionStack( cla = new ClassLiteralAccess(this.intStack[this.intPtr--], getTypeReference(this.intStack[this.intPtr--]))); rejectIllegalTypeAnnotations(cla.type, true /* tolerate annotations on dimensions for bug compatibility for now */); }
protected void consumePrimaryNoNewArrayPrimitiveType() { // PrimaryNoNewArray ::= PrimitiveType '.' 'class' this.intPtr--; // remove the class start position ClassLiteralAccess cla; pushOnExpressionStack( cla = new ClassLiteralAccess(this.intStack[this.intPtr--], getTypeReference(0))); rejectIllegalTypeAnnotations(cla.type); }
@Override public void endVisit(ClassLiteralAccess x, BlockScope scope) { try { SourceInfo info = makeSourceInfo(x); JType type = typeMap.get(x.targetType); push(new JClassLiteral(info, type)); } catch (Throwable e) { throw translateException(x, e); } }
public static void processAnnotation(LoggingFramework framework, AnnotationValues<? extends java.lang.annotation.Annotation> annotation, Annotation source, EclipseNode annotationNode) { EclipseNode owner = annotationNode.up(); switch (owner.getKind()) { case TYPE: TypeDeclaration typeDecl = null; if (owner.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) owner.get(); int modifiers = typeDecl == null ? 0 : typeDecl.modifiers; boolean notAClass = (modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation)) != 0; if (typeDecl == null || notAClass) { annotationNode.addError(framework.getAnnotationAsString() + " is legal only on classes and enums."); return; } if (fieldExists("log", owner) != MemberExistsResult.NOT_EXISTS) { annotationNode.addWarning("Field 'log' already exists."); return; } ClassLiteralAccess loggingType = selfType(owner, source); FieldDeclaration fieldDeclaration = createField(framework, source, loggingType); fieldDeclaration.traverse(new SetGeneratedByVisitor(source), typeDecl.staticInitializerScope); injectField(owner, fieldDeclaration); owner.rebuild(); break; default: break; } }
private static ClassLiteralAccess selfType(EclipseNode type, Annotation source) { int pS = source.sourceStart, pE = source.sourceEnd; long p = (long)pS << 32 | pE; TypeDeclaration typeDeclaration = (TypeDeclaration)type.get(); TypeReference typeReference = new SingleTypeReference(typeDeclaration.name, p); setGeneratedBy(typeReference, source); ClassLiteralAccess result = new ClassLiteralAccess(source.sourceEnd, typeReference); setGeneratedBy(result, source); return result; }
private static FieldDeclaration createField(LoggingFramework framework, Annotation source, ClassLiteralAccess loggingType) { int pS = source.sourceStart, pE = source.sourceEnd; long p = (long)pS << 32 | pE; // private static final <loggerType> log = <factoryMethod>(<parameter>); FieldDeclaration fieldDecl = new FieldDeclaration("log".toCharArray(), 0, -1); setGeneratedBy(fieldDecl, source); fieldDecl.declarationSourceEnd = -1; fieldDecl.modifiers = Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL; fieldDecl.type = createTypeReference(framework.getLoggerTypeName(), source); MessageSend factoryMethodCall = new MessageSend(); setGeneratedBy(factoryMethodCall, source); factoryMethodCall.receiver = createNameReference(framework.getLoggerFactoryTypeName(), source); factoryMethodCall.selector = framework.getLoggerFactoryMethodName().toCharArray(); Expression parameter = framework.createFactoryParameter(loggingType, source); factoryMethodCall.arguments = new Expression[] { parameter }; factoryMethodCall.nameSourcePosition = p; factoryMethodCall.sourceStart = pS; factoryMethodCall.sourceEnd = factoryMethodCall.statementEnd = pE; fieldDecl.initialization = factoryMethodCall; return fieldDecl; }
Expression createFactoryParameter(ClassLiteralAccess loggingType, Annotation source){ TypeReference copy = copyType(loggingType.type, source); ClassLiteralAccess result = new ClassLiteralAccess(source.sourceEnd, copy); setGeneratedBy(result, source); return result; }
@Override public boolean visit(ClassLiteralAccess node, BlockScope scope) { fixPositions(setGeneratedBy(node, source)); return super.visit(node, scope); }
public boolean visit( ClassLiteralAccess classLiteralAccess, BlockScope scope) { addRealFragment(classLiteralAccess); return false; }
protected Object getMemberValue(org.eclipse.jdt.internal.core.MemberValuePair memberValuePair, Expression expression) { if (expression instanceof NullLiteral) { return null; } else if (expression instanceof Literal) { ((Literal) expression).computeConstant(); return Util.getAnnotationMemberValue(memberValuePair, expression.constant); } else if (expression instanceof org.eclipse.jdt.internal.compiler.ast.Annotation) { org.eclipse.jdt.internal.compiler.ast.Annotation annotation = (org.eclipse.jdt.internal.compiler.ast.Annotation) expression; Object handle = acceptAnnotation(annotation, null, (JavaElement) this.handleStack.peek()); memberValuePair.valueKind = IMemberValuePair.K_ANNOTATION; return handle; } else if (expression instanceof ClassLiteralAccess) { ClassLiteralAccess classLiteral = (ClassLiteralAccess) expression; char[] name = CharOperation.concatWith(classLiteral.type.getTypeName(), '.'); memberValuePair.valueKind = IMemberValuePair.K_CLASS; return new String(name); } else if (expression instanceof QualifiedNameReference) { char[] qualifiedName = CharOperation.concatWith(((QualifiedNameReference) expression).tokens, '.'); memberValuePair.valueKind = IMemberValuePair.K_QUALIFIED_NAME; return new String(qualifiedName); } else if (expression instanceof SingleNameReference) { char[] simpleName = ((SingleNameReference) expression).token; if (simpleName == RecoveryScanner.FAKE_IDENTIFIER) { memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN; return null; } memberValuePair.valueKind = IMemberValuePair.K_SIMPLE_NAME; return new String(simpleName); } else if (expression instanceof ArrayInitializer) { memberValuePair.valueKind = -1; // modified below by the first call to getMemberValue(...) Expression[] expressions = ((ArrayInitializer) expression).expressions; int length = expressions == null ? 0 : expressions.length; Object[] values = new Object[length]; for (int i = 0; i < length; i++) { int previousValueKind = memberValuePair.valueKind; Object value = getMemberValue(memberValuePair, expressions[i]); if (previousValueKind != -1 && memberValuePair.valueKind != previousValueKind) { // values are heterogeneous, value kind is thus unknown memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN; } values[i] = value; } if (memberValuePair.valueKind == -1) memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN; return values; } else if (expression instanceof UnaryExpression) { // to deal with negative numerals (see bug - 248312) UnaryExpression unaryExpression = (UnaryExpression) expression; if ((unaryExpression.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT == OperatorIds.MINUS) { if (unaryExpression.expression instanceof Literal) { Literal subExpression = (Literal) unaryExpression.expression; subExpression.computeConstant(); return Util.getNegativeAnnotationMemberValue(memberValuePair, subExpression.constant); } } memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN; return null; } else { memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN; return null; } }
private Object getAnnotationMemberValue(MemberValuePair memberValuePair, Expression expression, JavaElement parentElement) { if (expression instanceof NullLiteral) { return null; } else if (expression instanceof Literal) { ((Literal) expression).computeConstant(); return Util.getAnnotationMemberValue(memberValuePair, expression.constant); } else if (expression instanceof org.eclipse.jdt.internal.compiler.ast.Annotation) { memberValuePair.valueKind = IMemberValuePair.K_ANNOTATION; return getAnnotation((org.eclipse.jdt.internal.compiler.ast.Annotation) expression, parentElement); } else if (expression instanceof ClassLiteralAccess) { ClassLiteralAccess classLiteral = (ClassLiteralAccess) expression; char[] typeName = CharOperation.concatWith(classLiteral.type.getTypeName(), '.'); memberValuePair.valueKind = IMemberValuePair.K_CLASS; return new String(typeName); } else if (expression instanceof QualifiedNameReference) { char[] qualifiedName = CharOperation.concatWith(((QualifiedNameReference) expression).tokens, '.'); memberValuePair.valueKind = IMemberValuePair.K_QUALIFIED_NAME; return new String(qualifiedName); } else if (expression instanceof SingleNameReference) { char[] simpleName = ((SingleNameReference) expression).token; if (simpleName == RecoveryScanner.FAKE_IDENTIFIER) { memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN; return null; } memberValuePair.valueKind = IMemberValuePair.K_SIMPLE_NAME; return new String(simpleName); } else if (expression instanceof ArrayInitializer) { memberValuePair.valueKind = -1; // modified below by the first call to getMemberValue(...) Expression[] expressions = ((ArrayInitializer) expression).expressions; int length = expressions == null ? 0 : expressions.length; Object[] values = new Object[length]; for (int i = 0; i < length; i++) { int previousValueKind = memberValuePair.valueKind; Object value = getAnnotationMemberValue(memberValuePair, expressions[i], parentElement); if (previousValueKind != -1 && memberValuePair.valueKind != previousValueKind) { // values are heterogeneous, value kind is thus unknown memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN; } values[i] = value; } if (memberValuePair.valueKind == -1) memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN; return values; } else if (expression instanceof UnaryExpression) { //to deal with negative numerals (see bug - 248312) UnaryExpression unaryExpression = (UnaryExpression) expression; if ((unaryExpression.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT == OperatorIds.MINUS) { if (unaryExpression.expression instanceof Literal) { Literal subExpression = (Literal) unaryExpression.expression; subExpression.computeConstant(); return Util.getNegativeAnnotationMemberValue(memberValuePair, subExpression.constant); } } memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN; return null; } else { memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN; return null; } }
@Override public boolean visit(ClassLiteralAccess node, BlockScope scope) { setGeneratedBy(node, source); applyOffsetExpression(node); return super.visit(node, scope); }