X-Git-Url: http://git.phpeclipse.com 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 index 0000000..e5a8376 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/dom/VariableBinding.java @@ -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(); + } +}