KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > codeassist > MissingTypesGuesser


1 /*******************************************************************************
2  * Copyright (c) 2006, 2007 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 package org.eclipse.jdt.internal.codeassist;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.HashMap JavaDoc;
15 import java.util.Set JavaDoc;
16
17 import org.eclipse.jdt.core.compiler.CharOperation;
18 import org.eclipse.jdt.core.search.IJavaSearchConstants;
19 import org.eclipse.jdt.internal.compiler.ASTVisitor;
20 import org.eclipse.jdt.internal.compiler.ast.*;
21 import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
22 import org.eclipse.jdt.internal.compiler.lookup.Binding;
23 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
24 import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
25 import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
26 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
27 import org.eclipse.jdt.internal.compiler.lookup.Scope;
28 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
29 import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt;
30 import org.eclipse.jdt.internal.core.SearchableEnvironment;
31
32 public class MissingTypesGuesser extends ASTVisitor {
33     public static interface GuessedTypeRequestor {
34         public void accept(
35                 TypeBinding guessedType,
36                 Binding[] missingElements,
37                 int[] missingElementsStarts,
38                 int[] missingElementsEnds,
39                 boolean hasProblems);
40         
41     }
42     
43     private static class ResolutionCleaner extends ASTVisitor {
44         private HashtableOfObjectToInt bitsMap = new HashtableOfObjectToInt();
45         private boolean firstCall = true;
46         
47         public ResolutionCleaner(){
48             super();
49         }
50         
51         private void cleanUp(TypeReference typeReference) {
52             if (this.firstCall) {
53                 this.bitsMap.put(typeReference, typeReference.bits);
54             } else {
55                 typeReference.bits = this.bitsMap.get(typeReference);
56             }
57             typeReference.resolvedType = null;
58         }
59         
60         private void cleanUp(ParameterizedSingleTypeReference typeReference) {
61             this.cleanUp((TypeReference)typeReference);
62             typeReference.bits &= ~ASTNode.DidResolve;
63         }
64         
65         private void cleanUp(ParameterizedQualifiedTypeReference typeReference) {
66             this.cleanUp((TypeReference)typeReference);
67             typeReference.bits &= ~ASTNode.DidResolve;
68         }
69         
70         public void cleanUp(TypeReference convertedType, BlockScope scope) {
71             convertedType.traverse(this, scope);
72             this.firstCall = false;
73         }
74
75         public void cleanUp(TypeReference convertedType, ClassScope scope) {
76             convertedType.traverse(this, scope);
77             this.firstCall = false;
78         }
79         
80         public boolean visit(SingleTypeReference singleTypeReference, BlockScope scope) {
81             this.cleanUp(singleTypeReference);
82             return true;
83         }
84         
85         public boolean visit(SingleTypeReference singleTypeReference, ClassScope scope) {
86             this.cleanUp(singleTypeReference);
87             return true;
88         }
89         
90         public boolean visit(Wildcard wildcard, BlockScope scope) {
91             this.cleanUp(wildcard);
92             return true;
93         }
94         
95         public boolean visit(Wildcard wildcard, ClassScope scope) {
96             this.cleanUp(wildcard);
97             return true;
98         }
99         
100         public boolean visit(ArrayTypeReference arrayTypeReference, BlockScope scope) {
101             this.cleanUp(arrayTypeReference);
102             return true;
103         }
104         
105         public boolean visit(ArrayTypeReference arrayTypeReference, ClassScope scope) {
106             this.cleanUp(arrayTypeReference);
107             return true;
108         }
109         
110         public boolean visit(ParameterizedSingleTypeReference parameterizedSingleTypeReference, BlockScope scope) {
111             this.cleanUp(parameterizedSingleTypeReference);
112             return true;
113         }
114         
115         public boolean visit(ParameterizedSingleTypeReference parameterizedSingleTypeReference, ClassScope scope) {
116             this.cleanUp(parameterizedSingleTypeReference);
117             return true;
118         }
119         
120         public boolean visit(QualifiedTypeReference qualifiedTypeReference, BlockScope scope) {
121             this.cleanUp(qualifiedTypeReference);
122             return true;
123         }
124         
125         public boolean visit(QualifiedTypeReference qualifiedTypeReference, ClassScope scope) {
126             this.cleanUp(qualifiedTypeReference);
127             return true;
128         }
129         
130         public boolean visit(ArrayQualifiedTypeReference arrayQualifiedTypeReference, BlockScope scope) {
131             this.cleanUp(arrayQualifiedTypeReference);
132             return true;
133         }
134         
135         public boolean visit(ArrayQualifiedTypeReference arrayQualifiedTypeReference, ClassScope scope) {
136             this.cleanUp(arrayQualifiedTypeReference);
137             return true;
138         }
139         
140         public boolean visit(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, BlockScope scope) {
141             this.cleanUp(parameterizedQualifiedTypeReference);
142             return true;
143         }
144         
145         public boolean visit(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, ClassScope scope) {
146             this.cleanUp(parameterizedQualifiedTypeReference);
147             return true;
148         }
149
150     }
151     
152     private CompletionEngine.CompletionProblemFactory problemFactory ;
153     private SearchableEnvironment nameEnvironment;
154     
155     private HashMap JavaDoc substituedTypes;
156     private HashMap JavaDoc originalTypes;
157     private int combinationsCount;
158             
159     public MissingTypesGuesser(CompletionEngine completionEngine) {
160         this.problemFactory = completionEngine.problemFactory;
161         this.nameEnvironment = completionEngine.nameEnvironment;
162     }
163     
164     private boolean computeMissingElements(
165             QualifiedTypeReference[] substituedTypeNodes,
166             char[][][] originalTypeNames,
167             Binding[] missingElements,
168             int[] missingElementsStarts,
169             int[] missingElementsEnds) {
170         int length = substituedTypeNodes.length;
171         
172         for (int i = 0; i < length; i++) {
173             TypeReference substituedType = substituedTypeNodes[i];
174             if (substituedType.resolvedType == null) return false;
175             ReferenceBinding erasure = (ReferenceBinding)substituedType.resolvedType.leafComponentType().erasure();
176             Binding missingElement;
177             int depthToRemove = originalTypeNames[i].length - 1 ;
178             if (depthToRemove == 0) {
179                 missingElement = erasure;
180             } else {
181                 int depth = erasure.depth() + 1;
182                 
183                 if (depth > depthToRemove) {
184                     missingElement = erasure.enclosingTypeAt(depthToRemove);
185                 } else {
186                     return false;
187                     ///////////////////////////////////////////////////////////
188
//// Uncomment the following code to return missing package
189
///////////////////////////////////////////////////////////
190
//depthToRemove -= depth;
191
//PackageBinding packageBinding = erasure.getPackage();
192
//while(depthToRemove > 0) {
193
// packageBinding = packageBinding.parent;
194
// depthToRemove--;
195
//}
196
//missingElement = packageBinding;
197
}
198             }
199             
200             missingElements[i] = missingElement;
201             missingElementsStarts[i] = substituedType.sourceStart;
202             missingElementsEnds[i] = substituedType.sourceEnd + 1;
203             
204         }
205         
206         return true;
207     }
208
209     private TypeReference convert(ArrayQualifiedTypeReference typeRef) {
210         if (typeRef.resolvedType != null) {
211             if (typeRef.resolvedType.isValidBinding()) {
212                 ArrayQualifiedTypeReference convertedType =
213                     new ArrayQualifiedTypeReference(
214                             typeRef.tokens,
215                             typeRef.dimensions(),
216                             typeRef.sourcePositions);
217                 convertedType.sourceStart = typeRef.sourceStart;
218                 convertedType.sourceEnd = typeRef.sourceEnd;
219                 return convertedType;
220             } else if((typeRef.resolvedType.problemId() & ProblemReasons.NotFound) != 0) {
221                 // only the first token must be resolved
222
if(((ReferenceBinding)typeRef.resolvedType.leafComponentType()).compoundName.length != 1) return null;
223                 
224                 char[][] typeName = typeRef.getTypeName();
225                 char[][][] typeNames = findTypeNames(typeName);
226                 if(typeNames == null || typeNames.length == 0) return null;
227                 ArrayQualifiedTypeReference convertedType =
228                     new ArrayQualifiedTypeReference(
229                             typeNames[0],
230                             typeRef.dimensions(),
231                             new long[typeNames[0].length]);
232                 convertedType.sourceStart = typeRef.sourceStart;
233                 convertedType.sourceEnd = (int)(typeRef.sourcePositions[0] & 0x00000000FFFFFFFFL);
234                 this.substituedTypes.put(convertedType, typeNames);
235                 this.originalTypes.put(convertedType, typeName);
236                 this.combinationsCount *= typeNames.length;
237                 return convertedType;
238             }
239         }
240         return null;
241     }
242
243     private TypeReference convert(ArrayTypeReference typeRef) {
244         if (typeRef.resolvedType != null) {
245             if (typeRef.resolvedType.isValidBinding()) {
246                 ArrayTypeReference convertedType =
247                     new ArrayTypeReference(
248                             typeRef.token,
249                             typeRef.dimensions,
250                             0);
251                 convertedType.sourceStart = typeRef.sourceStart;
252                 convertedType.sourceEnd = typeRef.originalSourceEnd;
253                 return convertedType;
254             } else if((typeRef.resolvedType.problemId() & ProblemReasons.NotFound) != 0) {
255                 char[][] typeName = typeRef.getTypeName();
256                 char[][][] typeNames = findTypeNames(typeName);
257                 if(typeNames == null || typeNames.length == 0) return null;
258                 ArrayQualifiedTypeReference convertedType =
259                     new ArrayQualifiedTypeReference(
260                             typeNames[0],
261                             typeRef.dimensions,
262                             new long[typeNames[0].length]);
263                 convertedType.sourceStart = typeRef.sourceStart;
264                 convertedType.sourceEnd = typeRef.originalSourceEnd;
265                 this.substituedTypes.put(convertedType, typeNames);
266                 this.originalTypes.put(convertedType, typeName);
267                 this.combinationsCount *= typeNames.length;
268                 return convertedType;
269             }
270         }
271         return null;
272     }
273     
274     private TypeReference convert(ParameterizedQualifiedTypeReference typeRef) {
275         if (typeRef.resolvedType != null) {
276             TypeReference[][] typeArguments = typeRef.typeArguments;
277             int length = typeArguments.length;
278             TypeReference[][] convertedTypeArguments = new TypeReference[length][];
279             next : for (int i = 0; i < length; i++) {
280                 if (typeArguments[i] == null) continue next;
281                 int length2 = typeArguments[i].length;
282                 convertedTypeArguments[i] = new TypeReference[length2];
283                 for (int j = 0; j < length2; j++) {
284                     convertedTypeArguments[i][j] = convert(typeArguments[i][j]);
285                     if (convertedTypeArguments[i][j] == null) return null;
286                 }
287             }
288             
289             if (typeRef.resolvedType.isValidBinding()) {
290                 ParameterizedQualifiedTypeReference convertedType =
291                     new ParameterizedQualifiedTypeReference(
292                             typeRef.tokens,
293                             convertedTypeArguments,
294                             typeRef.dimensions(),
295                             new long[typeRef.tokens.length]);
296                 convertedType.sourceStart = typeRef.sourceStart;
297                 convertedType.sourceEnd = typeRef.sourceEnd;
298                 return convertedType;
299             } else if((typeRef.resolvedType.problemId() & ProblemReasons.NotFound) != 0) {
300                 // only the first token must be resolved
301
if(((ReferenceBinding)typeRef.resolvedType.leafComponentType()).compoundName.length != 1) return null;
302                 
303                 char[][] typeName = typeRef.getTypeName();
304                 char[][][] typeNames = findTypeNames(typeName);
305                 if(typeNames == null || typeNames.length == 0) return null;
306                 
307                 TypeReference[][] newConvertedTypeArguments = new TypeReference[typeNames[0].length][];
308                 for (int k = newConvertedTypeArguments.length - 1, l = convertedTypeArguments.length -1; k > -1 && l > -1;) {
309                     newConvertedTypeArguments[k] = convertedTypeArguments[l];
310                     k--;
311                     l--;
312                 }
313                 
314                 ParameterizedQualifiedTypeReference convertedType =
315                     new ParameterizedQualifiedTypeReference(
316                             typeNames[0],
317                             newConvertedTypeArguments,
318                             typeRef.dimensions(),
319                             new long[typeNames[0].length]);
320                 convertedType.sourceStart = typeRef.sourceStart;
321                 convertedType.sourceEnd = (int)(typeRef.sourcePositions[0] & 0x00000000FFFFFFFFL);
322                 this.substituedTypes.put(convertedType, typeNames);
323                 this.originalTypes.put(convertedType, typeName);
324                 this.combinationsCount *= typeNames.length;
325                 return convertedType;
326             }
327         }
328         return null;
329     }
330     
331     private TypeReference convert(ParameterizedSingleTypeReference typeRef) {
332         if (typeRef.resolvedType != null) {
333             TypeReference[] typeArguments = typeRef.typeArguments;
334             int length = typeArguments.length;
335             TypeReference[] convertedTypeArguments = new TypeReference[length];
336             for (int i = 0; i < length; i++) {
337                 convertedTypeArguments[i] = convert(typeArguments[i]);
338                 if(convertedTypeArguments[i] == null) return null;
339             }
340             
341             if (typeRef.resolvedType.isValidBinding()) {
342                 ParameterizedSingleTypeReference convertedType =
343                     new ParameterizedSingleTypeReference(
344                             typeRef.token,
345                             convertedTypeArguments,
346                             typeRef.dimensions,
347                             0);
348                 convertedType.sourceStart = typeRef.sourceStart;
349                 convertedType.sourceEnd = typeRef.sourceEnd;
350                 return convertedType;
351             } else if((typeRef.resolvedType.problemId() & ProblemReasons.NotFound) != 0) {
352                 char[][] typeName = typeRef.getTypeName();
353                 char[][][] typeNames = findTypeNames(typeName);
354                 if(typeNames == null || typeNames.length == 0) return null;
355                 
356                 TypeReference[][] allConvertedTypeArguments = new TypeReference[typeNames[0].length][];
357                 allConvertedTypeArguments[allConvertedTypeArguments.length - 1] = convertedTypeArguments;
358                 
359                 ParameterizedQualifiedTypeReference convertedType =
360                     new ParameterizedQualifiedTypeReference(
361                             typeNames[0],
362                             allConvertedTypeArguments,
363                             typeRef.dimensions,
364                             new long[typeNames[0].length]);
365                 convertedType.sourceStart = typeRef.sourceStart;
366                 convertedType.sourceEnd = typeRef.sourceEnd;
367                 this.substituedTypes.put(convertedType, typeNames);
368                 this.originalTypes.put(convertedType, typeName);
369                 this.combinationsCount *= typeNames.length;
370                 return convertedType;
371             }
372         }
373         return null;
374     }
375     
376     private TypeReference convert(QualifiedTypeReference typeRef) {
377         if (typeRef.resolvedType != null) {
378             if (typeRef.resolvedType.isValidBinding()) {
379                 QualifiedTypeReference convertedType = new QualifiedTypeReference(typeRef.tokens, typeRef.sourcePositions);
380                 convertedType.sourceStart = typeRef.sourceStart;
381                 convertedType.sourceEnd = typeRef.sourceEnd;
382                 return convertedType;
383             } else if((typeRef.resolvedType.problemId() & ProblemReasons.NotFound) != 0) {
384                 // only the first token must be resolved
385
if(((ReferenceBinding)typeRef.resolvedType).compoundName.length != 1) return null;
386                 
387                 char[][] typeName = typeRef.getTypeName();
388                 char[][][] typeNames = findTypeNames(typeName);
389                 if(typeNames == null || typeNames.length == 0) return null;
390                 QualifiedTypeReference convertedType = new QualifiedTypeReference(typeNames[0], new long[typeNames[0].length]);
391                 convertedType.sourceStart = typeRef.sourceStart;
392                 convertedType.sourceEnd = (int)(typeRef.sourcePositions[0] & 0x00000000FFFFFFFFL);
393                 this.substituedTypes.put(convertedType, typeNames);
394                 this.originalTypes.put(convertedType, typeName);
395                 this.combinationsCount *= typeNames.length;
396                 return convertedType;
397             }
398         }
399         return null;
400     }
401     
402     private TypeReference convert(SingleTypeReference typeRef) {
403         if (typeRef.resolvedType != null) {
404             if (typeRef.resolvedType.isValidBinding()) {
405                 SingleTypeReference convertedType = new SingleTypeReference(typeRef.token, 0);
406                 convertedType.sourceStart = typeRef.sourceStart;
407                 convertedType.sourceEnd = typeRef.sourceEnd;
408                 return convertedType;
409             } else if((typeRef.resolvedType.problemId() & ProblemReasons.NotFound) != 0) {
410                 char[][] typeName = typeRef.getTypeName();
411                 char[][][] typeNames = findTypeNames(typeName);
412                 if(typeNames == null || typeNames.length == 0) return null;
413                 QualifiedTypeReference convertedType = new QualifiedTypeReference(typeNames[0], new long[typeNames[0].length]);
414                 convertedType.sourceStart = typeRef.sourceStart;
415                 convertedType.sourceEnd = typeRef.sourceEnd;
416                 this.substituedTypes.put(convertedType, typeNames);
417                 this.originalTypes.put(convertedType, typeName);
418                 this.combinationsCount *= typeNames.length;
419                 return convertedType;
420             }
421         }
422         return null;
423     }
424     
425     private TypeReference convert(TypeReference typeRef) {
426         if (typeRef instanceof ParameterizedSingleTypeReference) {
427             return convert((ParameterizedSingleTypeReference)typeRef);
428         } else if(typeRef instanceof ParameterizedQualifiedTypeReference) {
429             return convert((ParameterizedQualifiedTypeReference)typeRef);
430         } else if (typeRef instanceof ArrayTypeReference) {
431             return convert((ArrayTypeReference)typeRef);
432         } else if(typeRef instanceof ArrayQualifiedTypeReference) {
433             return convert((ArrayQualifiedTypeReference)typeRef);
434         } else if(typeRef instanceof Wildcard) {
435             return convert((Wildcard)typeRef);
436         } else if (typeRef instanceof SingleTypeReference) {
437             return convert((SingleTypeReference)typeRef);
438         } else if (typeRef instanceof QualifiedTypeReference) {
439             return convert((QualifiedTypeReference)typeRef);
440         }
441         return null;
442     }
443     
444     private TypeReference convert(Wildcard typeRef) {
445         TypeReference bound = typeRef.bound;
446         TypeReference convertedBound = null;
447         if (bound != null) {
448             convertedBound = convert(bound);
449             if (convertedBound == null) return null;
450         }
451         Wildcard convertedType = new Wildcard(typeRef.kind);
452         convertedType.bound = convertedBound;
453         convertedType.sourceStart = typeRef.sourceStart;
454         convertedType.sourceEnd = typeRef.sourceEnd;
455         return convertedType;
456     }
457     
458     private char[][][] findTypeNames(char[][] missingTypeName) {
459         char[] missingSimpleName = missingTypeName[missingTypeName.length - 1];
460         final boolean isQualified = missingTypeName.length > 1;
461         final char[] missingFullyQualifiedName =
462             isQualified ? CharOperation.concatWith(missingTypeName, '.') : null;
463         final ArrayList JavaDoc results = new ArrayList JavaDoc();
464         ISearchRequestor storage = new ISearchRequestor() {
465             
466             public void acceptPackage(char[] packageName) {
467                 // package aren't searched
468
}
469             public void acceptType(
470                     char[] packageName,
471                     char[] typeName,
472                     char[][] enclosingTypeNames,
473                     int modifiers,
474                     AccessRestriction accessRestriction) {
475                 char[] fullyQualifiedName = CharOperation.concat(packageName, CharOperation.concat(CharOperation.concatWith(enclosingTypeNames, '.'), typeName, '.'), '.');
476                 if (isQualified && !CharOperation.endsWith(fullyQualifiedName, missingFullyQualifiedName)) return;
477                 char[][] compoundName = CharOperation.splitOn('.', fullyQualifiedName);
478                 results.add(compoundName);
479             }
480         
481         };
482         nameEnvironment.findExactTypes(missingSimpleName, true, IJavaSearchConstants.TYPE, storage);
483         if(results.size() == 0) return null;
484         return (char[][][])results.toArray(new char[results.size()][0][0]);
485     }
486     
487     private char[][] getOriginal(TypeReference typeRef) {
488         return (char[][])this.originalTypes.get(typeRef);
489     }
490     
491     private QualifiedTypeReference[] getSubstituedTypes() {
492         Set JavaDoc types = this.substituedTypes.keySet();
493         return (QualifiedTypeReference[]) types.toArray(new QualifiedTypeReference[types.size()]);
494     }
495     
496     private char[][][] getSubstitution(TypeReference typeRef) {
497         return (char[][][])this.substituedTypes.get(typeRef);
498     }
499     
500     public void guess(TypeReference typeRef, Scope scope, GuessedTypeRequestor requestor) {
501         this.substituedTypes = new HashMap JavaDoc();
502         this.originalTypes = new HashMap JavaDoc();
503         this.combinationsCount = 1;
504         
505         TypeReference convertedType = convert(typeRef);
506         
507         if(convertedType == null) return;
508         
509         QualifiedTypeReference[] substituedTypeNodes = this.getSubstituedTypes();
510         int length = substituedTypeNodes.length;
511         
512         int[] substitutionsIndexes = new int[substituedTypeNodes.length];
513         char[][][][] subtitutions = new char[substituedTypeNodes.length][][][];
514         char[][][] originalTypeNames = new char[substituedTypeNodes.length][][];
515         for (int i = 0; i < substituedTypeNodes.length; i++) {
516             subtitutions[i] = this.getSubstitution(substituedTypeNodes[i]);
517             originalTypeNames[i] = this.getOriginal(substituedTypeNodes[i]);
518         }
519         
520         ResolutionCleaner resolutionCleaner = new ResolutionCleaner();
521         for (int i = 0; i < this.combinationsCount; i++) {
522             
523             nextSubstitution(substituedTypeNodes, subtitutions, substitutionsIndexes);
524             
525             
526             this.problemFactory.startCheckingProblems();
527             TypeBinding guessedType = null;
528             switch (scope.kind) {
529                 case Scope.METHOD_SCOPE :
530                 case Scope.BLOCK_SCOPE :
531                     resolutionCleaner.cleanUp(convertedType, (BlockScope)scope);
532                     guessedType = convertedType.resolveType((BlockScope)scope);
533                     break;
534                 case Scope.CLASS_SCOPE :
535                     resolutionCleaner.cleanUp(convertedType, (ClassScope)scope);
536                     guessedType = convertedType.resolveType((ClassScope)scope);
537                     break;
538             }
539             this.problemFactory.stopCheckingProblems();
540             if (!this.problemFactory.hasForbiddenProblems) {
541                 if (guessedType != null) {
542                     Binding[] missingElements = new Binding[length];
543                     int[] missingElementsStarts = new int[length];
544                     int[] missingElementsEnds = new int[length];
545                     
546                     if(computeMissingElements(
547                             substituedTypeNodes,
548                             originalTypeNames,
549                             missingElements,
550                             missingElementsStarts,
551                             missingElementsEnds)) {
552                         requestor.accept(
553                                 guessedType.capture(scope, typeRef.sourceEnd),
554                                 missingElements,
555                                 missingElementsStarts,
556                                 missingElementsEnds,
557                                 this.problemFactory.hasAllowedProblems);
558                     }
559                 }
560             }
561         }
562     }
563     private void nextSubstitution(
564             QualifiedTypeReference[] substituedTypeNodes,
565             char[][][][] subtitutions,
566             int[] substitutionsIndexes) {
567         int length = substituedTypeNodes.length;
568         
569         done : for (int i = 0; i < length; i++) {
570             if(substitutionsIndexes[i] < subtitutions[i].length - 1) {
571                 substitutionsIndexes[i]++;
572                 break done;
573             } else {
574                 substitutionsIndexes[i] = 0;
575             }
576         }
577         
578         for (int i = 0; i < length; i++) {
579             QualifiedTypeReference qualifiedTypeReference = substituedTypeNodes[i];
580             qualifiedTypeReference.tokens = subtitutions[i][substitutionsIndexes[i]];
581             qualifiedTypeReference.sourcePositions = new long[qualifiedTypeReference.tokens.length];
582             if(qualifiedTypeReference instanceof ParameterizedQualifiedTypeReference) {
583                 ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference =
584                     (ParameterizedQualifiedTypeReference)qualifiedTypeReference;
585                 TypeReference[][] typeArguments = parameterizedQualifiedTypeReference.typeArguments;
586                 TypeReference[][] newTypeArguments = new TypeReference[qualifiedTypeReference.tokens.length][];
587                 for (int j = newTypeArguments.length - 1, k = typeArguments.length -1; j > -1 && k > -1;) {
588                     newTypeArguments[j] = typeArguments[k];
589                     j--;
590                     k--;
591                 }
592             }
593         }
594     }
595 }
596
Popular Tags