1 /******************************************************************************* 2 * Copyright (c) 2000, 2009 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.jdt.internal.core; 15 16 import org.eclipse.jdt.core.IAnnotation; 17 import org.eclipse.jdt.core.IClassFile; 18 import org.eclipse.jdt.core.IMember; 19 import org.eclipse.jdt.core.IMemberValuePair; 20 import org.eclipse.jdt.core.ISourceRange; 21 import org.eclipse.jdt.core.JavaModelException; 22 import org.eclipse.jdt.core.SourceRange; 23 import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation; 24 import org.eclipse.jdt.internal.compiler.env.IBinaryElementValuePair; 25 import org.eclipse.jdt.internal.core.util.Util; 26 27 public class Annotation extends SourceRefElement implements IAnnotation { 28 29 public static final IAnnotation[] NO_ANNOTATIONS = new IAnnotation[0]; 30 public static final IMemberValuePair[] NO_MEMBER_VALUE_PAIRS = new IMemberValuePair[0]; 31 32 protected String name; 33 // require to distinguish same annotations in different member value pairs 34 protected String memberValuePairName; 35 Annotation(JavaElement parent, String name)36 public Annotation(JavaElement parent, String name) { 37 this(parent, name, null); 38 } 39 Annotation(JavaElement parent, String name, String memberValuePairName)40 public Annotation(JavaElement parent, String name, String memberValuePairName) { 41 super(parent); 42 this.name = name.intern(); 43 this.memberValuePairName = memberValuePairName; 44 } 45 46 @Override equals(Object o)47 public boolean equals(Object o) { 48 if (!(o instanceof Annotation)) { 49 return false; 50 } 51 Annotation other = (Annotation) o; 52 if (this.memberValuePairName == null) { 53 if (other.memberValuePairName != null) 54 return false; 55 } else if (!this.memberValuePairName.equals(other.memberValuePairName)) { 56 return false; 57 } 58 // name equality is checked as part of the super.equals(..) 59 return super.equals(o); 60 } 61 getDeclaringMember()62 public IMember getDeclaringMember() { 63 return (IMember) getParent(); 64 } 65 66 @Override getElementName()67 public String getElementName() { 68 return this.name; 69 } 70 71 @Override getElementType()72 public int getElementType() { 73 return ANNOTATION; 74 } 75 76 @Override getHandleMementoDelimiter()77 protected char getHandleMementoDelimiter() { 78 return JavaElement.JEM_ANNOTATION; 79 } 80 81 @Override getMemberValuePairs()82 public IMemberValuePair[] getMemberValuePairs() throws JavaModelException { 83 Object info = getElementInfo(); 84 if (info instanceof AnnotationInfo) 85 return ((AnnotationInfo) info).members; 86 IBinaryElementValuePair[] binaryAnnotations = ((IBinaryAnnotation) info).getElementValuePairs(); 87 int length = binaryAnnotations.length; 88 IMemberValuePair[] result = new IMemberValuePair[length]; 89 for (int i = 0; i < length; i++) { 90 IBinaryElementValuePair binaryAnnotation = binaryAnnotations[i]; 91 MemberValuePair memberValuePair = new MemberValuePair(new String(binaryAnnotation.getName())); 92 memberValuePair.value = Util.getAnnotationMemberValue(this, memberValuePair, binaryAnnotation.getValue()); 93 result[i] = memberValuePair; 94 } 95 return result; 96 } 97 98 @Override getNameRange()99 public ISourceRange getNameRange() throws JavaModelException { 100 SourceMapper mapper= getSourceMapper(); 101 if (mapper != null) { 102 IClassFile classFile = getClassFile(); 103 if (classFile != null) { 104 // ensure the class file's buffer is open so that source ranges are computed 105 classFile.getBuffer(); 106 return mapper.getNameRange(this); 107 } 108 } 109 Object info = getElementInfo(); 110 if (info instanceof AnnotationInfo) { 111 AnnotationInfo annotationInfo = (AnnotationInfo) info; 112 return new SourceRange(annotationInfo.nameStart, annotationInfo.nameEnd - annotationInfo.nameStart + 1); 113 } 114 return null; 115 } 116 117 /* 118 * @see ISourceReference 119 */ 120 @Override getSourceRange()121 public ISourceRange getSourceRange() throws JavaModelException { 122 SourceMapper mapper= getSourceMapper(); 123 if (mapper != null) { 124 // ensure the class file's buffer is open so that source ranges are computed 125 IClassFile classFile = getClassFile(); 126 if (classFile != null) { 127 classFile.getBuffer(); 128 return mapper.getSourceRange(this); 129 } 130 } 131 return super.getSourceRange(); 132 } 133 134 @Override getClassFile()135 public IClassFile getClassFile() { 136 return ((JavaElement)getParent()).getClassFile(); 137 } 138 139 @Override hashCode()140 public int hashCode() { 141 final int prime = 31; 142 int result = super.hashCode(); 143 result = prime * result + ((this.memberValuePairName == null) ? 0 : this.memberValuePairName.hashCode()); 144 result = prime * result + this.name.hashCode(); 145 return result; 146 } 147 148 @Override toStringName(StringBuffer buffer)149 protected void toStringName(StringBuffer buffer) { 150 buffer.append('@'); 151 buffer.append(getElementName()); 152 } 153 } 154