1cccc7f2b74564f2a8e864e6f4a99a2a7e0cab49
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / core / dom / RecoveredTypeBinding.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 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
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11
12 package net.sourceforge.phpdt.core.dom;
13
14 import java.util.List;
15
16 import net.sourceforge.phpdt.core.IJavaElement;
17 import net.sourceforge.phpdt.core.compiler.CharOperation;
18 import net.sourceforge.phpdt.internal.compiler.lookup.ArrayBinding;
19 import net.sourceforge.phpdt.internal.compiler.lookup.Binding;
20 import net.sourceforge.phpdt.internal.compiler.lookup.CompilationUnitScope;
21 import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding;
22 import net.sourceforge.phpdt.internal.compiler.util.SuffixConstants;
23 import net.sourceforge.phpdt.internal.compiler.util.Util;
24 import net.sourceforge.phpdt.internal.core.PackageFragment;
25
26 /**
27  * This class represents the recovered binding for a type
28  */
29 class RecoveredTypeBinding implements ITypeBinding {
30
31         private VariableDeclaration variableDeclaration;
32         private Type currentType;
33         private BindingResolver resolver;
34         private int dimensions;
35         private RecoveredTypeBinding innerTypeBinding;
36         private ITypeBinding[] typeArguments;
37         private net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding binding;
38
39         RecoveredTypeBinding(BindingResolver resolver, VariableDeclaration variableDeclaration) {
40                 this.variableDeclaration = variableDeclaration;
41                 this.resolver = resolver;
42                 this.currentType = getType();
43                 this.dimensions = variableDeclaration.getExtraDimensions();
44                 if (this.currentType.isArrayType()) {
45                         this.dimensions += ((ArrayType) this.currentType).getDimensions();
46                 }
47         }
48
49         RecoveredTypeBinding(BindingResolver resolver, net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding typeBinding) {
50                 this.resolver = resolver;
51                 this.dimensions = typeBinding.dimensions();
52                 this.binding = typeBinding;
53         }
54
55         RecoveredTypeBinding(BindingResolver resolver, Type type) {
56                 this.currentType = type;
57                 this.resolver = resolver;
58                 this.dimensions = 0;
59                 if (type.isArrayType()) {
60                         this.dimensions += ((ArrayType) type).getDimensions();
61                 }
62         }
63
64         RecoveredTypeBinding(BindingResolver resolver, RecoveredTypeBinding typeBinding, int dimensions) {
65                 this.innerTypeBinding = typeBinding;
66                 this.dimensions = typeBinding.getDimensions() + dimensions;
67                 this.resolver = resolver;
68         }
69
70         /* (non-Javadoc)
71          * @see org.eclipse.jdt.core.dom.ITypeBinding#createArrayType(int)
72          */
73         public ITypeBinding createArrayType(int dims) {
74                 return this.resolver.getTypeBinding(this, dims);
75         }
76
77         /* (non-Javadoc)
78          * @see org.eclipse.jdt.core.dom.ITypeBinding#getBinaryName()
79          */
80         public String getBinaryName() {
81                 return null;
82         }
83
84         /* (non-Javadoc)
85          * @see org.eclipse.jdt.core.dom.ITypeBinding#getBound()
86          */
87         public ITypeBinding getBound() {
88                 return null;
89         }
90
91         /* (non-Javadoc)
92          * @see org.eclipse.jdt.core.dom.ITypeBinding#getComponentType()
93          */
94         public ITypeBinding getComponentType() {
95                 if (this.dimensions == 0) return null;
96                 return this.resolver.getTypeBinding(this, -1);
97         }
98
99         /* (non-Javadoc)
100          * @see org.eclipse.jdt.core.dom.ITypeBinding#getDeclaredFields()
101          */
102         public IVariableBinding[] getDeclaredFields() {
103                 return TypeBinding.NO_VARIABLE_BINDINGS;
104         }
105
106         /* (non-Javadoc)
107          * @see org.eclipse.jdt.core.dom.ITypeBinding#getDeclaredMethods()
108          */
109         public IMethodBinding[] getDeclaredMethods() {
110                 return TypeBinding.NO_METHOD_BINDINGS;
111         }
112
113         /* (non-Javadoc)
114          * @see org.eclipse.jdt.core.dom.ITypeBinding#getDeclaredModifiers()
115          */
116         public int getDeclaredModifiers() {
117                 return 0;
118         }
119
120         /* (non-Javadoc)
121          * @see org.eclipse.jdt.core.dom.ITypeBinding#getDeclaredTypes()
122          */
123         public ITypeBinding[] getDeclaredTypes() {
124                 return TypeBinding.NO_TYPE_BINDINGS;
125         }
126
127         /* (non-Javadoc)
128          * @see org.eclipse.jdt.core.dom.ITypeBinding#getDeclaringClass()
129          */
130         public ITypeBinding getDeclaringClass() {
131                 return null;
132         }
133
134         /* (non-Javadoc)
135          * @see org.eclipse.jdt.core.dom.ITypeBinding#getDeclaringMethod()
136          */
137         public IMethodBinding getDeclaringMethod() {
138                 return null;
139         }
140
141         /* (non-Javadoc)
142          * @see org.eclipse.jdt.core.dom.ITypeBinding#getDimensions()
143          */
144         public int getDimensions() {
145                 return this.dimensions;
146         }
147
148         /* (non-Javadoc)
149          * @see org.eclipse.jdt.core.dom.ITypeBinding#getElementType()
150          */
151         public ITypeBinding getElementType() {
152                 if (this.binding != null) {
153                         if (this.binding.isArrayType()) {
154                                 ArrayBinding arrayBinding = (ArrayBinding) this.binding;
155                                 return new RecoveredTypeBinding(this.resolver, arrayBinding.leafComponentType);
156                         } else {
157                                 return new RecoveredTypeBinding(this.resolver, this.binding);
158                         }
159                 }
160                 if (this.innerTypeBinding != null) {
161                         return this.innerTypeBinding.getElementType();
162                 }
163                 if (this.currentType!= null && this.currentType.isArrayType()) {
164                         return this.resolver.getTypeBinding(((ArrayType) this.currentType).getElementType());
165                 }
166                 if (this.variableDeclaration != null && this.variableDeclaration.getExtraDimensions() != 0) {
167                         return this.resolver.getTypeBinding(getType());
168                 }
169                 return null;
170         }
171
172         /* (non-Javadoc)
173          * @see org.eclipse.jdt.core.dom.ITypeBinding#getErasure()
174          */
175         public ITypeBinding getErasure() {
176                 return this;
177         }
178
179         /* (non-Javadoc)
180          * @see org.eclipse.jdt.core.dom.ITypeBinding#getInterfaces()
181          */
182         public ITypeBinding[] getInterfaces() {
183                 return TypeBinding.NO_TYPE_BINDINGS;
184         }
185
186         /* (non-Javadoc)
187          * @see org.eclipse.jdt.core.dom.ITypeBinding#getModifiers()
188          */
189         public int getModifiers() {
190                 return Modifier.NONE;
191         }
192
193         /* (non-Javadoc)
194          * @see org.eclipse.jdt.core.dom.ITypeBinding#getName()
195          */
196         public String getName() {
197                 char[] brackets = new char[this.dimensions * 2];
198                 for (int i = this.dimensions * 2 - 1; i >= 0; i -= 2) {
199                         brackets[i] = ']';
200                         brackets[i - 1] = '[';
201                 }
202                 StringBuffer buffer = new StringBuffer(this.getInternalName());
203                 buffer.append(brackets);
204                 return String.valueOf(buffer);
205         }
206
207         private String getInternalName() {
208                 if (this.innerTypeBinding != null) {
209                         return this.innerTypeBinding.getInternalName();
210                 }
211                 ReferenceBinding referenceBinding = getReferenceBinding();
212                 if (referenceBinding != null) {
213                         return new String(referenceBinding.compoundName[referenceBinding.compoundName.length - 1]);
214                 }
215                 return this.getTypeNameFrom(getType());
216         }
217
218         /* (non-Javadoc)
219          * @see org.eclipse.jdt.core.dom.ITypeBinding#getPackage()
220          */
221         public IPackageBinding getPackage() {
222                 if (this.binding != null) {
223                         switch (this.binding.kind()) {
224                                 case Binding.BASE_TYPE :
225                                 case Binding.ARRAY_TYPE :
226                                 case Binding.TYPE_PARAMETER : // includes capture scenario
227                                 case Binding.WILDCARD_TYPE :
228                                 case Binding.INTERSECTION_TYPE:
229                                         return null;
230                         }
231                         IPackageBinding packageBinding = this.resolver.getPackageBinding(this.binding.getPackage());
232                         if (packageBinding != null) return packageBinding;
233                 }
234                 if (this.innerTypeBinding != null && this.dimensions > 0) {
235                         return null;
236                 }
237                 CompilationUnitScope scope = this.resolver.scope();
238                 if (scope != null) {
239                         return this.resolver.getPackageBinding(scope.getCurrentPackage());
240                 }
241                 return null;
242         }
243
244         /* (non-Javadoc)
245          * @see org.eclipse.jdt.core.dom.ITypeBinding#getQualifiedName()
246          */
247         public String getQualifiedName() {
248                 ReferenceBinding referenceBinding = getReferenceBinding();
249                 if (referenceBinding != null) {
250                         StringBuffer buffer = new StringBuffer();
251                         char[] brackets = new char[this.dimensions * 2];
252                         for (int i = this.dimensions * 2 - 1; i >= 0; i -= 2) {
253                                 brackets[i] = ']';
254                                 brackets[i - 1] = '[';
255                         }
256                         buffer.append(CharOperation.toString(referenceBinding.compoundName));
257                         buffer.append(brackets);
258                         return String.valueOf(buffer);
259                 } else { 
260                         return getName();
261                 }
262         }
263
264         private ReferenceBinding getReferenceBinding() {
265                 if (this.binding != null) {
266                         if (this.binding.isArrayType()) {
267                                 ArrayBinding arrayBinding = (ArrayBinding) this.binding;
268                                 if (arrayBinding.leafComponentType instanceof ReferenceBinding) {
269                                         return (ReferenceBinding) arrayBinding.leafComponentType;
270                                 }
271                         } else if (this.binding instanceof ReferenceBinding) {
272                                 return (ReferenceBinding) this.binding;
273                         }
274                 } else if (this.innerTypeBinding != null) {
275                         return this.innerTypeBinding.getReferenceBinding();
276                 }
277                 return null;
278         }
279
280         /* (non-Javadoc)
281          * @see org.eclipse.jdt.core.dom.ITypeBinding#getSuperclass()
282          */
283         public ITypeBinding getSuperclass() {
284                 if (getQualifiedName().equals("java.lang.Object")) {    //$NON-NLS-1$
285                         return null;
286                 }
287                 return this.resolver.resolveWellKnownType("java.lang.Object"); //$NON-NLS-1$
288         }
289
290         /* (non-Javadoc)
291          * @see org.eclipse.jdt.core.dom.ITypeBinding#getTypeArguments()
292          */
293         public ITypeBinding[] getTypeArguments() {
294                 if (this.binding != null) {
295                         return this.typeArguments = TypeBinding.NO_TYPE_BINDINGS;
296                 }
297                 if (this.typeArguments != null) {
298                         return typeArguments;
299                 }
300
301                 if (this.innerTypeBinding != null) {
302                         return this.innerTypeBinding.getTypeArguments();
303                 }
304
305                 if (this.currentType.isParameterizedType()) {
306                         ParameterizedType parameterizedType = (ParameterizedType) this.currentType;
307                         List typeArgumentsList = parameterizedType.typeArguments();
308                         int size = typeArgumentsList.size();
309                         ITypeBinding[] temp = new ITypeBinding[size];
310                         for (int i = 0; i < size; i++) {
311                                 ITypeBinding currentTypeBinding = ((Type) typeArgumentsList.get(i)).resolveBinding();
312                                 if (currentTypeBinding == null) {
313                                         return this.typeArguments = TypeBinding.NO_TYPE_BINDINGS;
314                                 }
315                                 temp[i] = currentTypeBinding;
316                         }
317                         return this.typeArguments = temp;
318                 }
319                 return this.typeArguments = TypeBinding.NO_TYPE_BINDINGS;
320         }
321
322         /* (non-Javadoc)
323          * @see org.eclipse.jdt.core.dom.ITypeBinding#getTypeBounds()
324          */
325         public ITypeBinding[] getTypeBounds() {
326                 return TypeBinding.NO_TYPE_BINDINGS;
327         }
328
329         /* (non-Javadoc)
330          * @see org.eclipse.jdt.core.dom.ITypeBinding#getTypeDeclaration()
331          */
332         public ITypeBinding getTypeDeclaration() {
333                 return this;
334         }
335
336         /* (non-Javadoc)
337          * @see org.eclipse.jdt.core.dom.ITypeBinding#getTypeParameters()
338          */
339         public ITypeBinding[] getTypeParameters() {
340                 return TypeBinding.NO_TYPE_BINDINGS;
341         }
342
343         /* (non-Javadoc)
344          * @see org.eclipse.jdt.core.dom.ITypeBinding#getWildcard()
345          */
346         public ITypeBinding getWildcard() {
347                 return null;
348         }
349
350         /* (non-Javadoc)
351          * @see org.eclipse.jdt.core.dom.ITypeBinding#isAnnotation()
352          */
353         public boolean isAnnotation() {
354                 return false;
355         }
356
357         /* (non-Javadoc)
358          * @see org.eclipse.jdt.core.dom.ITypeBinding#isAnonymous()
359          */
360         public boolean isAnonymous() {
361                 return false;
362         }
363
364         /* (non-Javadoc)
365          * @see org.eclipse.jdt.core.dom.ITypeBinding#isArray()
366          */
367         public boolean isArray() {
368                 return false;
369         }
370
371         /* (non-Javadoc)
372          * @see org.eclipse.jdt.core.dom.ITypeBinding#isAssignmentCompatible(org.eclipse.jdt.core.dom.ITypeBinding)
373          */
374         public boolean isAssignmentCompatible(ITypeBinding typeBinding) {
375                 if ("java.lang.Object".equals(typeBinding.getQualifiedName())) { //$NON-NLS-1$
376                         return true;
377                 }
378                 // since recovered binding are not unique isEqualTo is required
379                 return this.isEqualTo(typeBinding);
380         }
381
382         /* (non-Javadoc)
383          * @see org.eclipse.jdt.core.dom.ITypeBinding#isCapture()
384          */
385         public boolean isCapture() {
386                 return false;
387         }
388
389         /* (non-Javadoc)
390          * @see org.eclipse.jdt.core.dom.ITypeBinding#isCastCompatible(org.eclipse.jdt.core.dom.ITypeBinding)
391          */
392         public boolean isCastCompatible(ITypeBinding typeBinding) {
393                 if ("java.lang.Object".equals(typeBinding.getQualifiedName())) { //$NON-NLS-1$
394                         return true;
395                 }
396                 // since recovered binding are not unique isEqualTo is required
397                 return this.isEqualTo(typeBinding);
398         }
399
400         /* (non-Javadoc)
401          * @see org.eclipse.jdt.core.dom.ITypeBinding#isClass()
402          */
403         public boolean isClass() {
404                 return true;
405         }
406
407         /* (non-Javadoc)
408          * @see org.eclipse.jdt.core.dom.ITypeBinding#isEnum()
409          */
410         public boolean isEnum() {
411                 return false;
412         }
413
414         /* (non-Javadoc)
415          * @see org.eclipse.jdt.core.dom.ITypeBinding#isFromSource()
416          */
417         public boolean isFromSource() {
418                 return false;
419         }
420
421         /* (non-Javadoc)
422          * @see org.eclipse.jdt.core.dom.ITypeBinding#isGenericType()
423          */
424         public boolean isGenericType() {
425                 return false;
426         }
427
428         /* (non-Javadoc)
429          * @see org.eclipse.jdt.core.dom.ITypeBinding#isInterface()
430          */
431         public boolean isInterface() {
432                 return false;
433         }
434
435         /* (non-Javadoc)
436          * @see org.eclipse.jdt.core.dom.ITypeBinding#isLocal()
437          */
438         public boolean isLocal() {
439                 return false;
440         }
441
442         /* (non-Javadoc)
443          * @see org.eclipse.jdt.core.dom.ITypeBinding#isMember()
444          */
445         public boolean isMember() {
446                 return false;
447         }
448
449         /* (non-Javadoc)
450          * @see org.eclipse.jdt.core.dom.ITypeBinding#isNested()
451          */
452         public boolean isNested() {
453                 return false;
454         }
455
456         /* (non-Javadoc)
457          * @see org.eclipse.jdt.core.dom.ITypeBinding#isNullType()
458          */
459         public boolean isNullType() {
460                 return false;
461         }
462
463         /* (non-Javadoc)
464          * @see org.eclipse.jdt.core.dom.ITypeBinding#isParameterizedType()
465          */
466         public boolean isParameterizedType() {
467                 if (this.innerTypeBinding != null) {
468                         return this.innerTypeBinding.isParameterizedType();
469                 }
470                 if (this.currentType != null) {
471                         return this.currentType.isParameterizedType();
472                 }
473                 return false;
474         }
475
476         /* (non-Javadoc)
477          * @see org.eclipse.jdt.core.dom.ITypeBinding#isPrimitive()
478          */
479         public boolean isPrimitive() {
480                 return false;
481         }
482
483         /* (non-Javadoc)
484          * @see org.eclipse.jdt.core.dom.ITypeBinding#isRawType()
485          */
486         public boolean isRawType() {
487                 return false;
488         }
489
490         /* (non-Javadoc)
491          * @see org.eclipse.jdt.core.dom.ITypeBinding#isSubTypeCompatible(org.eclipse.jdt.core.dom.ITypeBinding)
492          */
493         public boolean isSubTypeCompatible(ITypeBinding typeBinding) {
494                 if ("java.lang.Object".equals(typeBinding.getQualifiedName())) { //$NON-NLS-1$
495                         return true;
496                 }
497                 // since recovered binding are not unique isEqualTo is required
498                 return this.isEqualTo(typeBinding);
499         }
500
501         /* (non-Javadoc)
502          * @see org.eclipse.jdt.core.dom.ITypeBinding#isTopLevel()
503          */
504         public boolean isTopLevel() {
505                 return true;
506         }
507
508         /* (non-Javadoc)
509          * @see org.eclipse.jdt.core.dom.ITypeBinding#isTypeVariable()
510          */
511         public boolean isTypeVariable() {
512                 return false;
513         }
514
515         /* (non-Javadoc)
516          * @see org.eclipse.jdt.core.dom.ITypeBinding#isUpperbound()
517          */
518         public boolean isUpperbound() {
519                 return false;
520         }
521
522         /* (non-Javadoc)
523          * @see org.eclipse.jdt.core.dom.ITypeBinding#isWildcardType()
524          */
525         public boolean isWildcardType() {
526                 return false;
527         }
528
529         /* (non-Javadoc)
530          * @see org.eclipse.jdt.core.dom.IBinding#getAnnotations()
531          */
532         public IAnnotationBinding[] getAnnotations() {
533                 return AnnotationBinding.NoAnnotations;
534         }
535
536         /* (non-Javadoc)
537          * @see org.eclipse.jdt.core.dom.IBinding#getJavaElement()
538          */
539         public IJavaElement getJavaElement() {
540                 IPackageBinding packageBinding = getPackage();
541                 if (packageBinding != null) {
542                         final IJavaElement javaElement = packageBinding.getJavaElement();
543                         if (javaElement != null && javaElement.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
544                                 // best effort: we don't know if the recovered binding is a binary or source binding, so go with a compilation unit
545                                 return ((PackageFragment) javaElement).getCompilationUnit(getInternalName() + SuffixConstants.SUFFIX_STRING_java);
546                         }
547                 }
548                 return null;
549         }
550
551         /* (non-Javadoc)
552          * @see org.eclipse.jdt.core.dom.IBinding#getKey()
553          */
554         public String getKey() {
555                 StringBuffer buffer = new StringBuffer();
556                 buffer.append("Recovered#"); //$NON-NLS-1$
557                 if (this.innerTypeBinding != null) {
558                         buffer.append("innerTypeBinding") //$NON-NLS-1$
559                               .append(this.innerTypeBinding.getKey());
560                 } else if (this.currentType != null) {
561                         buffer.append("currentType") //$NON-NLS-1$
562                               .append(this.currentType.toString());
563                 } else if (this.binding != null) {
564                         buffer.append("typeBinding") //$NON-NLS-1$
565                                   .append(this.binding.computeUniqueKey());
566                 } else if (variableDeclaration != null) {
567                         buffer
568                                 .append("variableDeclaration") //$NON-NLS-1$
569                                 .append(this.variableDeclaration.getClass())
570                                 .append(this.variableDeclaration.getName().getIdentifier())
571                                 .append(this.variableDeclaration.getExtraDimensions());
572                 }
573                 buffer.append(this.getDimensions());
574                 if (this.typeArguments != null) {
575                         buffer.append('<');
576                         for (int i = 0, max = this.typeArguments.length; i < max; i++) {
577                                 if (i != 0) {
578                                         buffer.append(',');
579                                 }
580                                 buffer.append(this.typeArguments[i].getKey());
581                         }
582                         buffer.append('>');
583                 }
584                 return String.valueOf(buffer);
585         }
586
587         /* (non-Javadoc)
588          * @see org.eclipse.jdt.core.dom.IBinding#getKind()
589          */
590         public int getKind() {
591                 return IBinding.TYPE;
592         }
593
594         /* (non-Javadoc)
595          * @see org.eclipse.jdt.core.dom.IBinding#isDeprecated()
596          */
597         public boolean isDeprecated() {
598                 return false;
599         }
600
601         /* (non-Javadoc)
602          * @see org.eclipse.jdt.core.dom.IBinding#isEqualTo(org.eclipse.jdt.core.dom.IBinding)
603          */
604         public boolean isEqualTo(IBinding other) {
605                 if (!other.isRecovered() || other.getKind() != IBinding.TYPE) return false;
606                 return this.getKey().equals(other.getKey());
607         }
608
609         /* (non-Javadoc)
610          * @see org.eclipse.jdt.core.dom.IBinding#isRecovered()
611          */
612         public boolean isRecovered() {
613                 return true;
614         }
615
616         /* (non-Javadoc)
617          * @see org.eclipse.jdt.core.dom.IBinding#isSynthetic()
618          */
619         public boolean isSynthetic() {
620                 return false;
621         }
622
623         private String getTypeNameFrom(Type type) {
624                 if (type == null) return Util.EMPTY_STRING;
625                 switch(type.getNodeType0()) {
626                         case ASTNode.ARRAY_TYPE :
627                                 ArrayType arrayType = (ArrayType) type;
628                                 type = arrayType.getElementType();
629                                 return getTypeNameFrom(type);
630                         case ASTNode.PARAMETERIZED_TYPE :
631                                 ParameterizedType parameterizedType = (ParameterizedType) type;
632                                 StringBuffer buffer = new StringBuffer(getTypeNameFrom(parameterizedType.getType()));
633                                 ITypeBinding[] tArguments = getTypeArguments();
634                                 final int typeArgumentsLength = tArguments.length;
635                                 if (typeArgumentsLength != 0) {
636                                         buffer.append('<');
637                                         for (int i = 0; i < typeArgumentsLength; i++) {
638                                                 if (i > 0) {
639                                                         buffer.append(',');
640                                                 }
641                                                 buffer.append(tArguments[i].getName());
642                                         }
643                                         buffer.append('>');
644                                 }
645                                 return String.valueOf(buffer);
646                         case ASTNode.PRIMITIVE_TYPE :
647                                 PrimitiveType primitiveType = (PrimitiveType) type;
648                                 return primitiveType.getPrimitiveTypeCode().toString();
649                         case ASTNode.QUALIFIED_TYPE :
650                                 QualifiedType qualifiedType = (QualifiedType) type;
651                                 return qualifiedType.getName().getIdentifier();
652                         case ASTNode.SIMPLE_TYPE :
653                                 SimpleType simpleType = (SimpleType) type;
654                                 Name name = simpleType.getName();
655                                 if (name.isQualifiedName()) {
656                                         QualifiedName qualifiedName = (QualifiedName) name;
657                                         return qualifiedName.getName().getIdentifier();
658                                 }
659                                 return ((SimpleName) name).getIdentifier();
660                 }
661                 return Util.EMPTY_STRING;
662         }
663
664         private Type getType() {
665                 if (this.currentType != null) {
666                         return this.currentType;
667                 }
668                 if (this.variableDeclaration == null) return null;
669                 switch(this.variableDeclaration.getNodeType()) {
670                         case ASTNode.SINGLE_VARIABLE_DECLARATION :
671                                 SingleVariableDeclaration singleVariableDeclaration = (SingleVariableDeclaration) this.variableDeclaration;
672                                 return singleVariableDeclaration.getType();
673                         default :
674                                 // this is a variable declaration fragment
675                                 ASTNode parent = this.variableDeclaration.getParent();
676                                 switch(parent.getNodeType()) {
677                                         case ASTNode.VARIABLE_DECLARATION_EXPRESSION :
678                                                 VariableDeclarationExpression variableDeclarationExpression = (VariableDeclarationExpression) parent;
679                                                 return variableDeclarationExpression.getType();
680                                         case ASTNode.VARIABLE_DECLARATION_STATEMENT :
681                                                 VariableDeclarationStatement statement = (VariableDeclarationStatement) parent;
682                                                 return statement.getType();
683                                         case ASTNode.FIELD_DECLARATION :
684                                                 FieldDeclaration fieldDeclaration  = (FieldDeclaration) parent;
685                                                 return fieldDeclaration.getType();
686                                 }
687                 }
688                 return null; // should not happen
689         }
690 }