/******************************************************************************* * Copyright (c) 2000, 2010 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 org.eclipse.che.ide.ext.java.jdt.core.dom; import org.eclipse.che.ide.ext.java.jdt.core.util.ModifierConstants; import org.eclipse.che.ide.ext.java.jdt.internal.compiler.ClassFileConstants; import org.eclipse.che.ide.ext.java.jdt.internal.compiler.ast.AbstractMethodDeclaration; import org.eclipse.che.ide.ext.java.jdt.internal.compiler.ast.Initializer; import org.eclipse.che.ide.ext.java.jdt.internal.compiler.impl.Constant; import org.eclipse.che.ide.ext.java.jdt.internal.compiler.impl.ReferenceContext; import org.eclipse.che.ide.ext.java.jdt.internal.compiler.lookup.BlockScope; import org.eclipse.che.ide.ext.java.jdt.internal.compiler.lookup.FieldBinding; import org.eclipse.che.ide.ext.java.jdt.internal.compiler.lookup.LocalVariableBinding; import org.eclipse.che.ide.ext.java.jdt.internal.compiler.lookup.TagBits; import org.eclipse.che.ide.ext.java.jdt.internal.compiler.lookup.TypeIds; /** 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 org.eclipse.che.ide.ext.java.jdt.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, org.eclipse.che.ide.ext.java.jdt.internal.compiler.lookup.VariableBinding binding) { this.resolver = resolver; this.binding = binding; } public IAnnotationBinding[] getAnnotations() { if (this.annotations != null) { return this.annotations; } org.eclipse.che.ide.ext.java.jdt.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++) { org.eclipse.che.ide.ext.java.jdt.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) { if (this.binding instanceof LocalVariableBinding) { LocalVariableBinding localVariableBinding = (LocalVariableBinding)this.binding; BlockScope blockScope = localVariableBinding.declaringScope; if (blockScope != null) { ReferenceContext referenceContext = blockScope.referenceContext(); if (referenceContext instanceof Initializer) { return null; } if (referenceContext instanceof AbstractMethodDeclaration) { return this.resolver.getMethodBinding(((AbstractMethodDeclaration)referenceContext).binding); } } } return null; } 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#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 (this.binding.isFinal()) { return ModifierConstants.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; // if (!defaultBindingResolver.fromJavaProject) return null; // return Util.getUnresolvedJavaElement( // (FieldBinding) this.binding, // defaultBindingResolver.getBindingsToNodesMap()); // } // return null; // } // // local variable // if (!(this.resolver instanceof DefaultBindingResolver)) return null; // DefaultBindingResolver defaultBindingResolver = (DefaultBindingResolver) this.resolver; // if (!defaultBindingResolver.fromJavaProject) return null; // VariableDeclaration localVar = (VariableDeclaration) defaultBindingResolver.bindingsToAstNodes.get(this); // if (localVar == null) return null; // int nameStart; // int nameLength; // int sourceStart; // int sourceLength; // int modifiers = 0; // if (localVar instanceof SingleVariableDeclaration) { // sourceStart = localVar.getStartPosition(); // sourceLength = localVar.getLength(); // final SingleVariableDeclaration singleVariableDeclaration = (SingleVariableDeclaration) localVar; // SimpleName simpleName = singleVariableDeclaration.getName(); // nameStart = simpleName.getStartPosition(); // nameLength = simpleName.getLength(); // modifiers = singleVariableDeclaration.getModifiers(); // } else { // nameStart = localVar.getStartPosition(); // nameLength = localVar.getLength(); // ASTNode node = localVar.getParent(); // sourceStart = node.getStartPosition(); // sourceLength = node.getLength(); // VariableDeclarationFragment fragment = (VariableDeclarationFragment) localVar; // final ASTNode parent = fragment.getParent(); // switch (parent.getNodeType()) { // case ASTNode.VARIABLE_DECLARATION_EXPRESSION : // VariableDeclarationExpression expression = (VariableDeclarationExpression) parent; // modifiers = expression.getModifiers(); // break; // case ASTNode.VARIABLE_DECLARATION_STATEMENT : // VariableDeclarationStatement statement = (VariableDeclarationStatement) parent; // modifiers = statement.getModifiers(); // break; // case ASTNode.FIELD_DECLARATION : // FieldDeclaration fieldDeclaration = (FieldDeclaration) parent; // modifiers = fieldDeclaration.getModifiers(); // break; // } // } // int sourceEnd = sourceStart+sourceLength-1; // char[] typeSig = this.binding.type.genericTypeSignature(); // JavaElement parent = null; // IMethodBinding declaringMethod = getDeclaringMethod(); // final LocalVariableBinding localVariableBinding = (LocalVariableBinding) this.binding; // if (declaringMethod == null) { // ReferenceContext referenceContext = localVariableBinding.declaringScope.referenceContext(); // if (referenceContext instanceof TypeDeclaration){ // // Local variable is declared inside an initializer // TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext; // JavaElement typeHandle = null; // typeHandle = Util.getUnresolvedJavaElement( // typeDeclaration.binding, // defaultBindingResolver.getBindingsToNodesMap()); // parent = Util.getUnresolvedJavaElement(sourceStart, sourceEnd, typeHandle); // } else { // return null; // } // } else { // parent = (JavaElement) declaringMethod.getJavaElement(); // } // if (parent == null) return null; // return new LocalVariable( // parent, // localVar.getName().getIdentifier(), // sourceStart, // sourceEnd, // nameStart, // nameStart+nameLength-1, // new String(typeSig), // localVariableBinding.declaration.annotations, // modifiers, // (localVariableBinding.tagBits & TagBits.IsArgument) != 0); // } /* * @see IVariableBinding#getVariableDeclaration() * @since 3.1 */ public IVariableBinding getVariableDeclaration() { if (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; } org.eclipse.che.ide.ext.java.jdt.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 = 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(); } }