1 /*******************************************************************************
2 * Copyright (c) 2000, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
12 package net.sourceforge.phpdt.core.dom;
14 import net.sourceforge.phpdt.core.IJavaElement;
15 import net.sourceforge.phpdt.core.util.IModifierConstants;
16 import net.sourceforge.phpdt.internal.compiler.classfmt.ClassFileConstants;
17 import net.sourceforge.phpdt.internal.compiler.impl.Constant;
18 import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding;
19 import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding;
20 import net.sourceforge.phpdt.internal.compiler.lookup.TagBits;
21 import net.sourceforge.phpdt.internal.compiler.lookup.TypeIds;
22 import net.sourceforge.phpdt.internal.core.JavaElement;
23 import net.sourceforge.phpdt.internal.core.LocalVariable;
24 import net.sourceforge.phpdt.internal.core.util.Util;
27 * Internal implementation of variable bindings.
29 class VariableBinding implements IVariableBinding {
31 private static final int VALID_MODIFIERS = Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE |
32 Modifier.STATIC | Modifier.FINAL | Modifier.TRANSIENT | Modifier.VOLATILE;
34 private net.sourceforge.phpdt.internal.compiler.lookup.VariableBinding binding;
35 private ITypeBinding declaringClass;
38 private BindingResolver resolver;
39 private ITypeBinding type;
40 private IAnnotationBinding[] annotations;
42 VariableBinding(BindingResolver resolver,net.sourceforge.phpdt.internal.compiler.lookup.VariableBinding binding) {
43 this.resolver = resolver;
44 this.binding = binding;
47 public IAnnotationBinding[] getAnnotations() {
48 if (this.annotations != null) {
49 return this.annotations;
51 net.sourceforge.phpdt.internal.compiler.lookup.AnnotationBinding[] internalAnnotations = this.binding.getAnnotations();
52 int length = internalAnnotations == null ? 0 : internalAnnotations.length;
54 IAnnotationBinding[] tempAnnotations = new IAnnotationBinding[length];
55 int convertedAnnotationCount = 0;
56 for (int i = 0; i < length; i++) {
57 net.sourceforge.phpdt.internal.compiler.lookup.AnnotationBinding internalAnnotation = internalAnnotations[i];
58 final IAnnotationBinding annotationInstance = this.resolver.getAnnotationInstance(internalAnnotation);
59 if (annotationInstance == null) {
62 tempAnnotations[convertedAnnotationCount++] = annotationInstance;
64 if (convertedAnnotationCount != length) {
65 if (convertedAnnotationCount == 0) {
66 return this.annotations = AnnotationBinding.NoAnnotations;
68 System.arraycopy(tempAnnotations, 0, (tempAnnotations = new IAnnotationBinding[convertedAnnotationCount]), 0, convertedAnnotationCount);
70 return this.annotations = tempAnnotations;
72 return this.annotations = AnnotationBinding.NoAnnotations;
76 * @see IVariableBinding#getConstantValue()
79 public Object getConstantValue() {
80 Constant c = this.binding.constant();
81 if (c == null || c == Constant.NotAConstant) return null;
83 case TypeIds.T_boolean:
84 return Boolean.valueOf(c.booleanValue());
86 return new Byte(c.byteValue());
88 return new Character(c.charValue());
89 case TypeIds.T_double:
90 return new Double(c.doubleValue());
92 return new Float(c.floatValue());
94 return new Integer(c.intValue());
96 return new Long(c.longValue());
98 return new Short(c.shortValue());
99 case TypeIds.T_JavaLangString:
100 return c.stringValue();
106 * @see IVariableBinding#getDeclaringClass()
108 public ITypeBinding getDeclaringClass() {
110 if (this.declaringClass == null) {
111 FieldBinding fieldBinding = (FieldBinding) this.binding;
112 this.declaringClass = this.resolver.getTypeBinding(fieldBinding.declaringClass);
114 return this.declaringClass;
121 * @see IVariableBinding#getDeclaringMethod()
123 public IMethodBinding getDeclaringMethod() {
125 ASTNode node = this.resolver.findDeclaringNode(this);
127 if (node == null) break;
128 switch(node.getNodeType()) {
129 case ASTNode.INITIALIZER :
131 case ASTNode.METHOD_DECLARATION :
132 MethodDeclaration methodDeclaration = (MethodDeclaration) node;
133 return methodDeclaration.resolveBinding();
135 node = node.getParent();
143 * @see IBinding#getJavaElement()
145 public IJavaElement getJavaElement() {
146 JavaElement element = getUnresolvedJavaElement();
149 return element.resolved(this.binding);
153 * @see IBinding#getKey()
155 public String getKey() {
156 if (this.key == null) {
157 this.key = new String(this.binding.computeUniqueKey());
163 * @see IBinding#getKind()
165 public int getKind() {
166 return IBinding.VARIABLE;
170 * @see IBinding#getModifiers()
172 public int getModifiers() {
174 return ((FieldBinding) this.binding).getAccessFlags() & VALID_MODIFIERS;
176 if (binding.isFinal()) {
177 return IModifierConstants.ACC_FINAL;
179 return Modifier.NONE;
183 * @see IBinding#getName()
185 public String getName() {
186 if (this.name == null) {
187 this.name = new String(this.binding.name);
193 * @see IVariableBinding#getType()
195 public ITypeBinding getType() {
196 if (this.type == null) {
197 this.type = this.resolver.getTypeBinding(this.binding.type);
202 private JavaElement getUnresolvedJavaElement() {
204 if (this.resolver instanceof DefaultBindingResolver) {
205 DefaultBindingResolver defaultBindingResolver = (DefaultBindingResolver) this.resolver;
206 return Util.getUnresolvedJavaElement(
207 (FieldBinding) this.binding,
208 defaultBindingResolver.workingCopyOwner,
209 defaultBindingResolver.getBindingsToNodesMap());
211 return Util.getUnresolvedJavaElement((FieldBinding) this.binding, null, null);
215 IMethodBinding declaringMethod = getDeclaringMethod();
216 if (declaringMethod == null) return null;
217 JavaElement method = (JavaElement) declaringMethod.getJavaElement();
218 if (method == null) return null;
219 if (!(this.resolver instanceof DefaultBindingResolver)) return null;
220 VariableDeclaration localVar = (VariableDeclaration) ((DefaultBindingResolver) this.resolver).bindingsToAstNodes.get(this);
221 if (localVar == null) return null;
226 if (localVar instanceof SingleVariableDeclaration) {
227 sourceStart = localVar.getStartPosition();
228 sourceLength = localVar.getLength();
229 SimpleName simpleName = ((SingleVariableDeclaration) localVar).getName();
230 nameStart = simpleName.getStartPosition();
231 nameLength = simpleName.getLength();
233 nameStart = localVar.getStartPosition();
234 nameLength = localVar.getLength();
235 ASTNode node = localVar.getParent();
236 sourceStart = node.getStartPosition();
237 sourceLength = node.getLength();
239 char[] typeSig = this.binding.type.genericTypeSignature();
240 return new LocalVariable(method, localVar.getName().getIdentifier(), sourceStart, sourceStart+sourceLength-1, nameStart, nameStart+nameLength-1, new String(typeSig), ((LocalVariableBinding) this.binding).declaration.annotations);
244 * @see IVariableBinding#getVariableDeclaration()
247 public IVariableBinding getVariableDeclaration() {
248 if (this.isField()) {
249 FieldBinding fieldBinding = (FieldBinding) this.binding;
250 return this.resolver.getVariableBinding(fieldBinding.original());
256 * @see IVariableBinding#getVariableId()
258 public int getVariableId() {
259 return this.binding.id;
263 * @see IVariableBinding#isParameter()
265 public boolean isParameter() {
266 return (this.binding.tagBits & TagBits.IsArgument) != 0;
269 * @see IBinding#isDeprecated()
271 public boolean isDeprecated() {
273 return ((FieldBinding) this.binding).isDeprecated();
279 * @see IVariableBinding#isEnumConstant()
282 public boolean isEnumConstant() {
283 return (this.binding.modifiers & ClassFileConstants.AccEnum) != 0;
287 * @see IBinding#isEqualTo(Binding)
290 public boolean isEqualTo(IBinding other) {
292 // identical binding - equal (key or no key)
296 // other binding missing
299 if (!(other instanceof VariableBinding)) {
302 net.sourceforge.phpdt.internal.compiler.lookup.VariableBinding otherBinding = ((VariableBinding) other).binding;
303 if (this.binding instanceof FieldBinding) {
304 if (otherBinding instanceof FieldBinding) {
305 return BindingComparator.isEqual((FieldBinding) this.binding, (FieldBinding) otherBinding);
310 if (BindingComparator.isEqual(this.binding, otherBinding)) {
311 IMethodBinding declaringMethod = this.getDeclaringMethod();
312 IMethodBinding otherDeclaringMethod = ((VariableBinding) other).getDeclaringMethod();
313 if (declaringMethod == null) {
314 if (otherDeclaringMethod != null) {
319 return declaringMethod.isEqualTo(otherDeclaringMethod);
326 * @see IVariableBinding#isField()
328 public boolean isField() {
329 return this.binding instanceof FieldBinding;
333 * @see IBinding#isSynthetic()
335 public boolean isSynthetic() {
337 return ((FieldBinding) this.binding).isSynthetic();
344 * @see org.eclipse.jdt.core.dom.IBinding#isRecovered()
346 public boolean isRecovered() {
351 * For debugging purpose only.
352 * @see java.lang.Object#toString()
354 public String toString() {
355 return this.binding.toString();