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