private IAnnotation getAnnotation( final org.eclipse.jdt.internal.compiler.ast.Annotation annotation, JavaElement parentElement) { final int typeStart = annotation.type.sourceStart(); final int typeEnd = annotation.type.sourceEnd(); final int sourceStart = annotation.sourceStart(); final int sourceEnd = annotation.declarationSourceEnd; class LocalVarAnnotation extends Annotation { IMemberValuePair[] memberValuePairs; public LocalVarAnnotation(JavaElement localVar, String elementName) { super(localVar, elementName); } public IMemberValuePair[] getMemberValuePairs() throws JavaModelException { return this.memberValuePairs; } public ISourceRange getNameRange() throws JavaModelException { return new SourceRange(typeStart, typeEnd - typeStart + 1); } public ISourceRange getSourceRange() throws JavaModelException { return new SourceRange(sourceStart, sourceEnd - sourceStart + 1); } public boolean exists() { return this.parent.exists(); } } String annotationName = new String(CharOperation.concatWith(annotation.type.getTypeName(), '.')); LocalVarAnnotation localVarAnnotation = new LocalVarAnnotation(parentElement, annotationName); org.eclipse.jdt.internal.compiler.ast.MemberValuePair[] astMemberValuePairs = annotation.memberValuePairs(); int length; IMemberValuePair[] memberValuePairs; if (astMemberValuePairs == null || (length = astMemberValuePairs.length) == 0) { memberValuePairs = Annotation.NO_MEMBER_VALUE_PAIRS; } else { memberValuePairs = new IMemberValuePair[length]; for (int i = 0; i < length; i++) { org.eclipse.jdt.internal.compiler.ast.MemberValuePair astMemberValuePair = astMemberValuePairs[i]; MemberValuePair memberValuePair = new MemberValuePair(new String(astMemberValuePair.name)); memberValuePair.value = getAnnotationMemberValue(memberValuePair, astMemberValuePair.value, localVarAnnotation); memberValuePairs[i] = memberValuePair; } } localVarAnnotation.memberValuePairs = memberValuePairs; return localVarAnnotation; }
// public int match(Reference node, MatchingNodeSet nodeSet) - SKIP IT public int match(Annotation node, MatchingNodeSet nodeSet) { if (!this.pattern.findReferences) return IMPOSSIBLE_MATCH; MemberValuePair[] pairs = node.memberValuePairs(); if (pairs == null || pairs.length == 0) return IMPOSSIBLE_MATCH; int length = pairs.length; MemberValuePair pair = null; for (int i = 0; i < length; i++) { pair = node.memberValuePairs()[i]; if (matchesName(this.pattern.selector, pair.name)) { ASTNode possibleNode = (node instanceof SingleMemberAnnotation) ? (ASTNode) node : pair; return nodeSet.addMatch( possibleNode, this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH); } } return IMPOSSIBLE_MATCH; }
private int readTargetValue(int offset) { int currentOffset = offset; int tag = u1At(currentOffset); currentOffset++; switch (tag) { case 'e': int utf8Offset = this.constantPoolOffsets[u2At(currentOffset)] - this.structOffset; char[] typeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1)); currentOffset += 2; if (typeName.length == 34 && CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_ELEMENTTYPE)) { utf8Offset = this.constantPoolOffsets[u2At(currentOffset)] - this.structOffset; char[] constName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1)); this.standardAnnotationTagBits |= Annotation.getTargetElementType(constName); } currentOffset += 2; break; case 'B': case 'C': case 'D': case 'F': case 'I': case 'J': case 'S': case 'Z': case 's': case 'c': currentOffset += 2; break; case '@': // none of the supported standard annotation are in the nested // level. currentOffset = scanAnnotation(currentOffset, false, false); break; case '[': int numberOfValues = u2At(currentOffset); currentOffset += 2; if (numberOfValues == 0) { this.standardAnnotationTagBits |= TagBits.AnnotationTarget; } else { for (int i = 0; i < numberOfValues; i++) currentOffset = readTargetValue(currentOffset); } break; default: throw new IllegalStateException(); } return currentOffset; }
/** Provides AnnotationValues with the data it needs to do its thing. */ public static <A extends java.lang.annotation.Annotation> AnnotationValues<A> createAnnotation( Class<A> type, final Node annotationNode) { final Annotation annotation = (Annotation) annotationNode.get(); Map<String, AnnotationValue> values = new HashMap<String, AnnotationValue>(); final MemberValuePair[] pairs = annotation.memberValuePairs(); for (Method m : type.getDeclaredMethods()) { if (!Modifier.isPublic(m.getModifiers())) continue; String name = m.getName(); List<String> raws = new ArrayList<String>(); List<Object> guesses = new ArrayList<Object>(); Expression fullExpression = null; Expression[] expressions = null; if (pairs != null) for (MemberValuePair pair : pairs) { char[] n = pair.name; String mName = n == null ? "value" : new String(pair.name); if (mName.equals(name)) fullExpression = pair.value; } boolean isExplicit = fullExpression != null; if (isExplicit) { if (fullExpression instanceof ArrayInitializer) { expressions = ((ArrayInitializer) fullExpression).expressions; } else expressions = new Expression[] {fullExpression}; if (expressions != null) for (Expression ex : expressions) { StringBuffer sb = new StringBuffer(); ex.print(0, sb); raws.add(sb.toString()); guesses.add(calculateValue(ex)); } } final Expression fullExpr = fullExpression; final Expression[] exprs = expressions; values.put( name, new AnnotationValue(annotationNode, raws, guesses, isExplicit) { @Override public void setError(String message, int valueIdx) { Expression ex; if (valueIdx == -1) ex = fullExpr; else ex = exprs != null ? exprs[valueIdx] : null; if (ex == null) ex = annotation; int sourceStart = ex.sourceStart; int sourceEnd = ex.sourceEnd; annotationNode.addError(message, sourceStart, sourceEnd); } @Override public void setWarning(String message, int valueIdx) { Expression ex; if (valueIdx == -1) ex = fullExpr; else ex = exprs != null ? exprs[valueIdx] : null; if (ex == null) ex = annotation; int sourceStart = ex.sourceStart; int sourceEnd = ex.sourceEnd; annotationNode.addWarning(message, sourceStart, sourceEnd); } }); } return new AnnotationValues<A>(type, values, annotationNode); }