Initial upgrade to Platform/JDT 3.4.1
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / core / dom / VariableBinding.java
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/dom/VariableBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/dom/VariableBinding.java
new file mode 100644 (file)
index 0000000..e5a8376
--- /dev/null
@@ -0,0 +1,357 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.core.dom;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.util.IModifierConstants;
+import net.sourceforge.phpdt.internal.compiler.classfmt.ClassFileConstants;
+import net.sourceforge.phpdt.internal.compiler.impl.Constant;
+import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding;
+import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding;
+import net.sourceforge.phpdt.internal.compiler.lookup.TagBits;
+import net.sourceforge.phpdt.internal.compiler.lookup.TypeIds;
+import net.sourceforge.phpdt.internal.core.JavaElement;
+import net.sourceforge.phpdt.internal.core.LocalVariable;
+import net.sourceforge.phpdt.internal.core.util.Util;
+
+/**
+ * Internal implementation of variable bindings.
+ */
+class VariableBinding implements IVariableBinding {
+
+       private static final int VALID_MODIFIERS = Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE |
+               Modifier.STATIC | Modifier.FINAL | Modifier.TRANSIENT | Modifier.VOLATILE;
+
+       private net.sourceforge.phpdt.internal.compiler.lookup.VariableBinding binding;
+       private ITypeBinding declaringClass;
+       private String key;
+       private String name;
+       private BindingResolver resolver;
+       private ITypeBinding type;
+       private IAnnotationBinding[] annotations;
+       
+       VariableBinding(BindingResolver resolver,net.sourceforge.phpdt.internal.compiler.lookup.VariableBinding binding) {
+               this.resolver = resolver;
+               this.binding = binding;
+       }
+
+       public IAnnotationBinding[] getAnnotations() {
+               if (this.annotations != null) {
+                       return this.annotations;
+               }
+               net.sourceforge.phpdt.internal.compiler.lookup.AnnotationBinding[] internalAnnotations = this.binding.getAnnotations();
+               int length = internalAnnotations == null ? 0 : internalAnnotations.length;
+               if (length != 0) {
+                       IAnnotationBinding[] tempAnnotations = new IAnnotationBinding[length];
+                       int convertedAnnotationCount = 0;
+                       for (int i = 0; i < length; i++) {
+                               net.sourceforge.phpdt.internal.compiler.lookup.AnnotationBinding internalAnnotation = internalAnnotations[i];
+                               final IAnnotationBinding annotationInstance = this.resolver.getAnnotationInstance(internalAnnotation);
+                               if (annotationInstance == null) {
+                                       continue;
+                               }
+                               tempAnnotations[convertedAnnotationCount++] = annotationInstance;
+                       }
+                       if (convertedAnnotationCount != length) {
+                               if (convertedAnnotationCount == 0) {
+                                       return this.annotations = AnnotationBinding.NoAnnotations;
+                               }
+                               System.arraycopy(tempAnnotations, 0, (tempAnnotations = new IAnnotationBinding[convertedAnnotationCount]), 0, convertedAnnotationCount);
+                       }
+                       return this.annotations = tempAnnotations;
+               }
+               return this.annotations = AnnotationBinding.NoAnnotations;
+       }
+
+       /* (non-Javadoc)
+        * @see IVariableBinding#getConstantValue()
+        * @since 3.0
+        */
+       public Object getConstantValue() {
+               Constant c = this.binding.constant();
+               if (c == null || c == Constant.NotAConstant) return null;
+               switch (c.typeID()) {
+                       case TypeIds.T_boolean:
+                               return Boolean.valueOf(c.booleanValue());
+                       case TypeIds.T_byte:
+                               return new Byte(c.byteValue());
+                       case TypeIds.T_char:
+                               return new Character(c.charValue());
+                       case TypeIds.T_double:
+                               return new Double(c.doubleValue());
+                       case TypeIds.T_float:
+                               return new Float(c.floatValue());
+                       case TypeIds.T_int:
+                               return new Integer(c.intValue());
+                       case TypeIds.T_long:
+                               return new Long(c.longValue());
+                       case TypeIds.T_short:
+                               return new Short(c.shortValue());
+                       case TypeIds.T_JavaLangString:
+                               return c.stringValue();
+               }
+               return null;
+       }
+
+       /*
+        * @see IVariableBinding#getDeclaringClass()
+        */
+       public ITypeBinding getDeclaringClass() {
+               if (isField()) {
+                       if (this.declaringClass == null) {
+                               FieldBinding fieldBinding = (FieldBinding) this.binding;
+                               this.declaringClass = this.resolver.getTypeBinding(fieldBinding.declaringClass);
+                       }
+                       return this.declaringClass;
+               } else {
+                       return null;
+               }
+       }
+
+       /*
+        * @see IVariableBinding#getDeclaringMethod()
+        */
+       public IMethodBinding getDeclaringMethod() {
+               if (!isField()) {
+                       ASTNode node = this.resolver.findDeclaringNode(this);
+                       while (true) {
+                               if (node == null) break;
+                               switch(node.getNodeType()) {
+                                       case ASTNode.INITIALIZER :
+                                               return null;
+                                       case ASTNode.METHOD_DECLARATION :
+                                               MethodDeclaration methodDeclaration = (MethodDeclaration) node;
+                                               return methodDeclaration.resolveBinding();
+                                       default:
+                                               node = node.getParent();
+                               }
+                       }
+               }
+               return null;
+       }
+
+       /*
+        * @see IBinding#getJavaElement()
+        */
+       public IJavaElement getJavaElement() {
+               JavaElement element = getUnresolvedJavaElement();
+               if (element == null)
+                       return null;
+               return element.resolved(this.binding);
+       }
+
+       /*
+        * @see IBinding#getKey()
+        */
+       public String getKey() {
+               if (this.key == null) {
+                       this.key = new String(this.binding.computeUniqueKey());
+               }
+               return this.key;
+       }
+
+       /*
+        * @see IBinding#getKind()
+        */
+       public int getKind() {
+               return IBinding.VARIABLE;
+       }
+
+       /*
+        * @see IBinding#getModifiers()
+        */
+       public int getModifiers() {
+               if (isField()) {
+                       return ((FieldBinding) this.binding).getAccessFlags() & VALID_MODIFIERS;
+               }
+               if (binding.isFinal()) {
+                       return IModifierConstants.ACC_FINAL;
+               }
+               return Modifier.NONE;
+       }
+
+       /*
+        * @see IBinding#getName()
+        */
+       public String getName() {
+               if (this.name == null) {
+                       this.name = new String(this.binding.name);
+               }
+               return this.name;
+       }
+
+       /*
+        * @see IVariableBinding#getType()
+        */
+       public ITypeBinding getType() {
+               if (this.type == null) {
+                       this.type = this.resolver.getTypeBinding(this.binding.type);
+               }
+               return this.type;
+       }
+
+       private JavaElement getUnresolvedJavaElement() {
+               if (isField()) {
+                       if (this.resolver instanceof DefaultBindingResolver) {
+                               DefaultBindingResolver defaultBindingResolver = (DefaultBindingResolver) this.resolver;
+                               return Util.getUnresolvedJavaElement(
+                                               (FieldBinding) this.binding,
+                                               defaultBindingResolver.workingCopyOwner,
+                                               defaultBindingResolver.getBindingsToNodesMap());
+                       } else {
+                               return Util.getUnresolvedJavaElement((FieldBinding) this.binding, null, null);
+                       }
+               }
+               // local variable
+               IMethodBinding declaringMethod = getDeclaringMethod();
+               if (declaringMethod == null) return null;
+               JavaElement method = (JavaElement) declaringMethod.getJavaElement();
+               if (method == null) return null;
+               if (!(this.resolver instanceof DefaultBindingResolver)) return null;
+               VariableDeclaration localVar = (VariableDeclaration) ((DefaultBindingResolver) this.resolver).bindingsToAstNodes.get(this);
+               if (localVar == null) return null;
+               int nameStart;
+               int nameLength;
+               int sourceStart;
+               int sourceLength;
+               if (localVar instanceof SingleVariableDeclaration) {
+                       sourceStart = localVar.getStartPosition();
+                       sourceLength = localVar.getLength();
+                       SimpleName simpleName = ((SingleVariableDeclaration) localVar).getName();
+                       nameStart = simpleName.getStartPosition();
+                       nameLength = simpleName.getLength();
+               } else {
+                       nameStart =  localVar.getStartPosition();
+                       nameLength = localVar.getLength();
+                       ASTNode node = localVar.getParent();
+                       sourceStart = node.getStartPosition();
+                       sourceLength = node.getLength();
+               }
+               char[] typeSig = this.binding.type.genericTypeSignature();
+               return new LocalVariable(method, localVar.getName().getIdentifier(), sourceStart, sourceStart+sourceLength-1, nameStart, nameStart+nameLength-1, new String(typeSig), ((LocalVariableBinding) this.binding).declaration.annotations);
+       }
+
+       /*
+        * @see IVariableBinding#getVariableDeclaration()
+        * @since 3.1
+        */
+       public IVariableBinding getVariableDeclaration() {
+               if (this.isField()) {
+                       FieldBinding fieldBinding = (FieldBinding) this.binding;
+                       return this.resolver.getVariableBinding(fieldBinding.original());
+               }
+               return this;
+       }
+
+       /*
+        * @see IVariableBinding#getVariableId()
+        */
+       public int getVariableId() {
+               return this.binding.id;
+       }
+
+       /*
+        * @see IVariableBinding#isParameter()
+        */
+       public boolean isParameter() {
+               return (this.binding.tagBits & TagBits.IsArgument) != 0;
+       }
+       /*
+        * @see IBinding#isDeprecated()
+        */
+       public boolean isDeprecated() {
+               if (isField()) {
+                       return ((FieldBinding) this.binding).isDeprecated();
+               }
+               return false;
+       }
+
+       /*
+        * @see IVariableBinding#isEnumConstant()
+        * @since 3.1
+        */
+       public boolean isEnumConstant() {
+               return (this.binding.modifiers & ClassFileConstants.AccEnum) != 0;
+       }
+
+       /*
+        * @see IBinding#isEqualTo(Binding)
+        * @since 3.1
+        */
+       public boolean isEqualTo(IBinding other) {
+               if (other == this) {
+                       // identical binding - equal (key or no key)
+                       return true;
+               }
+               if (other == null) {
+                       // other binding missing
+                       return false;
+               }
+               if (!(other instanceof VariableBinding)) {
+                       return false;
+               }
+               net.sourceforge.phpdt.internal.compiler.lookup.VariableBinding otherBinding = ((VariableBinding) other).binding;
+               if (this.binding instanceof FieldBinding) {
+                       if (otherBinding instanceof FieldBinding) {
+                               return BindingComparator.isEqual((FieldBinding) this.binding, (FieldBinding) otherBinding);
+                       } else {
+                               return false;
+                       }
+               } else {
+                       if (BindingComparator.isEqual(this.binding, otherBinding)) {
+                               IMethodBinding declaringMethod = this.getDeclaringMethod();
+                               IMethodBinding otherDeclaringMethod = ((VariableBinding) other).getDeclaringMethod();
+                               if (declaringMethod == null) {
+                                       if (otherDeclaringMethod != null) {
+                                               return false;
+                                       }
+                                       return true;
+                               }
+                               return declaringMethod.isEqualTo(otherDeclaringMethod);
+                       }
+                       return false;
+               }
+       }
+
+       /*
+        * @see IVariableBinding#isField()
+        */
+       public boolean isField() {
+               return this.binding instanceof FieldBinding;
+       }
+
+       /*
+        * @see IBinding#isSynthetic()
+        */
+       public boolean isSynthetic() {
+               if (isField()) {
+                       return ((FieldBinding) this.binding).isSynthetic();
+               }
+               return false;
+       }
+
+       /*
+        * (non-Javadoc)
+        * @see org.eclipse.jdt.core.dom.IBinding#isRecovered()
+        */
+       public boolean isRecovered() {
+               return false;
+       }
+
+       /*
+        * For debugging purpose only.
+        * @see java.lang.Object#toString()
+        */
+       public String toString() {
+               return this.binding.toString();
+       }
+}