KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 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.Locale JavaDoc;
14 import java.util.Map JavaDoc;
15
16 import org.eclipse.jdt.core.Signature;
17 import org.eclipse.jdt.core.compiler.*;
18 import org.eclipse.jdt.core.search.IJavaSearchConstants;
19 import org.eclipse.jdt.internal.codeassist.impl.*;
20 import org.eclipse.jdt.internal.codeassist.select.*;
21 import org.eclipse.jdt.internal.compiler.*;
22 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
23 import org.eclipse.jdt.internal.compiler.env.*;
24 import org.eclipse.jdt.internal.compiler.ast.*;
25 import org.eclipse.jdt.internal.compiler.lookup.*;
26 import org.eclipse.jdt.internal.compiler.parser.*;
27 import org.eclipse.jdt.internal.compiler.problem.*;
28 import org.eclipse.jdt.internal.core.SearchableEnvironment;
29 import org.eclipse.jdt.internal.core.SelectionRequestor;
30 import org.eclipse.jdt.internal.core.SourceType;
31 import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
32 import org.eclipse.jdt.internal.core.util.ASTNodeFinder;
33
34 /**
35  * The selection engine is intended to infer the nature of a selected name in some
36  * source code. This name can be qualified.
37  *
38  * Selection is resolving context using a name environment (no need to search), assuming
39  * the source where selection occurred is correct and will not perform any completion
40  * attempt. If this was the desired behavior, a call to the CompletionEngine should be
41  * performed instead.
42  */

43 public final class SelectionEngine extends Engine implements ISearchRequestor {
44
45     public static boolean DEBUG = false;
46     public static boolean PERF = false;
47     
48     SelectionParser parser;
49     ISelectionRequestor requestor;
50
51     boolean acceptedAnswer;
52
53     private int actualSelectionStart;
54     private int actualSelectionEnd;
55     private char[] selectedIdentifier;
56     
57     private char[][][] acceptedClasses;
58     private int[] acceptedClassesModifiers;
59     private char[][][] acceptedInterfaces;
60     private int[] acceptedInterfacesModifiers;
61     private char[][][] acceptedEnums;
62     private int[] acceptedEnumsModifiers;
63     private char[][][] acceptedAnnotations;
64     private int[] acceptedAnnotationsModifiers;
65     int acceptedClassesCount;
66     int acceptedInterfacesCount;
67     int acceptedEnumsCount;
68     int acceptedAnnotationsCount;
69     
70     boolean noProposal = true;
71     CategorizedProblem problem = null;
72
73     /**
74      * The SelectionEngine is responsible for computing the selected object.
75      *
76      * It requires a searchable name environment, which supports some
77      * specific search APIs, and a requestor to feed back the results to a UI.
78      *
79      * @param nameEnvironment org.eclipse.jdt.internal.core.SearchableEnvironment
80      * used to resolve type/package references and search for types/packages
81      * based on partial names.
82      *
83      * @param requestor org.eclipse.jdt.internal.codeassist.ISelectionRequestor
84      * since the engine might produce answers of various forms, the engine
85      * is associated with a requestor able to accept all possible completions.
86      *
87      * @param settings java.util.Map
88      * set of options used to configure the code assist engine.
89      */

90     public SelectionEngine(
91         SearchableEnvironment nameEnvironment,
92         ISelectionRequestor requestor,
93         Map JavaDoc settings) {
94
95         super(settings);
96
97         this.requestor = requestor;
98         this.nameEnvironment = nameEnvironment;
99
100         ProblemReporter problemReporter =
101             new ProblemReporter(
102                 DefaultErrorHandlingPolicies.proceedWithAllProblems(),
103                 this.compilerOptions,
104                 new DefaultProblemFactory(Locale.getDefault())) {
105                     
106             public CategorizedProblem createProblem(
107                 char[] fileName,
108                 int problemId,
109                 String JavaDoc[] problemArguments,
110                 String JavaDoc[] messageArguments,
111                 int severity,
112                 int problemStartPosition,
113                 int problemEndPosition,
114                 int lineNumber,
115                 int columnNumber) {
116                 CategorizedProblem pb = super.createProblem(
117                     fileName,
118                     problemId,
119                     problemArguments,
120                     messageArguments,
121                     severity,
122                     problemStartPosition,
123                     problemEndPosition,
124                     lineNumber,
125                     columnNumber);
126                     if(SelectionEngine.this.problem == null && pb.isError() && (pb.getID() & IProblem.Syntax) == 0) {
127                         SelectionEngine.this.problem = pb;
128                     }
129
130                     return pb;
131             }
132         };
133         this.lookupEnvironment =
134             new LookupEnvironment(this, this.compilerOptions, problemReporter, nameEnvironment);
135         this.parser = new SelectionParser(problemReporter);
136     }
137
138     public void acceptType(char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, int modifiers, AccessRestriction accessRestriction) {
139         char[] typeName = enclosingTypeNames == null ?
140                 simpleTypeName :
141                     CharOperation.concat(
142                         CharOperation.concatWith(enclosingTypeNames, '.'),
143                         simpleTypeName,
144                         '.');
145         
146         if (CharOperation.equals(simpleTypeName, this.selectedIdentifier)) {
147             char[] flatEnclosingTypeNames =
148                 enclosingTypeNames == null || enclosingTypeNames.length == 0 ?
149                         null :
150                             CharOperation.concatWith(enclosingTypeNames, '.');
151             if(mustQualifyType(packageName, simpleTypeName, flatEnclosingTypeNames, modifiers)) {
152                 int length = 0;
153                 int kind = modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation);
154                 switch (kind) {
155                     case ClassFileConstants.AccAnnotation:
156                     case ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface:
157                         char[][] acceptedAnnotation = new char[2][];
158                         acceptedAnnotation[0] = packageName;
159                         acceptedAnnotation[1] = typeName;
160                         
161                         if(this.acceptedAnnotations == null) {
162                             this.acceptedAnnotations = new char[10][][];
163                             this.acceptedAnnotationsModifiers = new int[10];
164                             this.acceptedAnnotationsCount = 0;
165                         }
166                         length = this.acceptedAnnotations.length;
167                         if(length == this.acceptedAnnotationsCount) {
168                             int newLength = (length + 1)* 2;
169                             System.arraycopy(this.acceptedAnnotations, 0, this.acceptedAnnotations = new char[newLength][][], 0, length);
170                             System.arraycopy(this.acceptedAnnotationsModifiers, 0, this.acceptedAnnotationsModifiers = new int[newLength], 0, length);
171                         }
172                         this.acceptedAnnotationsModifiers[this.acceptedAnnotationsCount] = modifiers;
173                         this.acceptedAnnotations[this.acceptedAnnotationsCount++] = acceptedAnnotation;
174                         break;
175                     case ClassFileConstants.AccEnum:
176                         char[][] acceptedEnum = new char[2][];
177                         acceptedEnum[0] = packageName;
178                         acceptedEnum[1] = typeName;
179                         
180                         if(this.acceptedEnums == null) {
181                             this.acceptedEnums = new char[10][][];
182                             this.acceptedEnumsModifiers = new int[10];
183                             this.acceptedEnumsCount = 0;
184                         }
185                         length = this.acceptedEnums.length;
186                         if(length == this.acceptedEnumsCount) {
187                             int newLength = (length + 1)* 2;
188                             System.arraycopy(this.acceptedEnums, 0, this.acceptedEnums = new char[newLength][][], 0, length);
189                             System.arraycopy(this.acceptedEnumsModifiers, 0, this.acceptedEnumsModifiers = new int[newLength], 0, length);
190                         }
191                         this.acceptedEnumsModifiers[this.acceptedEnumsCount] = modifiers;
192                         this.acceptedEnums[this.acceptedEnumsCount++] = acceptedEnum;
193                         break;
194                     case ClassFileConstants.AccInterface:
195                         char[][] acceptedInterface= new char[2][];
196                         acceptedInterface[0] = packageName;
197                         acceptedInterface[1] = typeName;
198                         
199                         if(this.acceptedInterfaces == null) {
200                             this.acceptedInterfaces = new char[10][][];
201                             this.acceptedInterfacesModifiers = new int[10];
202                             this.acceptedInterfacesCount = 0;
203                         }
204                         length = this.acceptedInterfaces.length;
205                         if(length == this.acceptedInterfacesCount) {
206                             int newLength = (length + 1)* 2;
207                             System.arraycopy(this.acceptedInterfaces, 0, this.acceptedInterfaces = new char[newLength][][], 0, length);
208                             System.arraycopy(this.acceptedInterfacesModifiers, 0, this.acceptedInterfacesModifiers = new int[newLength], 0, length);
209                         }
210                         this.acceptedInterfacesModifiers[this.acceptedInterfacesCount] = modifiers;
211                         this.acceptedInterfaces[this.acceptedInterfacesCount++] = acceptedInterface;
212                         break;
213                     default:
214                         char[][] acceptedClass = new char[2][];
215                         acceptedClass[0] = packageName;
216                         acceptedClass[1] = typeName;
217                         
218                         if(this.acceptedClasses == null) {
219                             this.acceptedClasses = new char[10][][];
220                             this.acceptedClassesModifiers = new int[10];
221                             this.acceptedClassesCount = 0;
222                         }
223                         length = this.acceptedClasses.length;
224                         if(length == this.acceptedClassesCount) {
225                             int newLength = (length + 1)* 2;
226                             System.arraycopy(this.acceptedClasses, 0, this.acceptedClasses = new char[newLength][][], 0, length);
227                             System.arraycopy(this.acceptedClassesModifiers, 0, this.acceptedClassesModifiers = new int[newLength], 0, length);
228                         }
229                         this.acceptedClassesModifiers[this.acceptedClassesCount] = modifiers;
230                         this.acceptedClasses[this.acceptedClassesCount++] = acceptedClass;
231                         break;
232                 }
233             } else {
234                 this.noProposal = false;
235                 this.requestor.acceptType(
236                     packageName,
237                     typeName,
238                     modifiers,
239                     false,
240                     null,
241                     this.actualSelectionStart,
242                     this.actualSelectionEnd);
243                 this.acceptedAnswer = true;
244             }
245         }
246     }
247
248     /**
249      * One result of the search consists of a new package.
250      * @param packageName char[]
251      *
252      * NOTE - All package names are presented in their readable form:
253      * Package names are in the form "a.b.c".
254      * The default package is represented by an empty array.
255      */

256     public void acceptPackage(char[] packageName) {
257         // implementation of interface method
258
}
259
260     private void acceptQualifiedTypes() {
261         if(this.acceptedClasses != null){
262             this.acceptedAnswer = true;
263             for (int i = 0; i < this.acceptedClassesCount; i++) {
264                 this.noProposal = false;
265                 this.requestor.acceptType(
266                     this.acceptedClasses[i][0],
267                     this.acceptedClasses[i][1],
268                     this.acceptedClassesModifiers[i],
269                     false,
270                     null,
271                     this.actualSelectionStart,
272                     this.actualSelectionEnd);
273             }
274             this.acceptedClasses = null;
275             this.acceptedClassesModifiers = null;
276             this.acceptedClassesCount = 0;
277         }
278         if(this.acceptedInterfaces != null){
279             this.acceptedAnswer = true;
280             for (int i = 0; i < this.acceptedInterfacesCount; i++) {
281                 this.noProposal = false;
282                 this.requestor.acceptType(
283                     this.acceptedInterfaces[i][0],
284                     this.acceptedInterfaces[i][1],
285                     this.acceptedInterfacesModifiers[i],
286                     false,
287                     null,
288                     this.actualSelectionStart,
289                     this.actualSelectionEnd);
290             }
291             this.acceptedInterfaces = null;
292             this.acceptedInterfacesModifiers = null;
293             this.acceptedInterfacesCount = 0;
294         }
295         if(this.acceptedAnnotations != null){
296             this.acceptedAnswer = true;
297             for (int i = 0; i < this.acceptedAnnotationsCount; i++) {
298                 this.noProposal = false;
299                 this.requestor.acceptType(
300                     this.acceptedAnnotations[i][0],
301                     this.acceptedAnnotations[i][1],
302                     this.acceptedAnnotationsModifiers[i],
303                     false,
304                     null,
305                     this.actualSelectionStart,
306                     this.actualSelectionEnd);
307             }
308             this.acceptedAnnotations = null;
309             this.acceptedAnnotationsModifiers = null;
310             this.acceptedAnnotationsCount = 0;
311         }
312         if(this.acceptedEnums != null){
313             this.acceptedAnswer = true;
314             for (int i = 0; i < this.acceptedEnumsCount; i++) {
315                 this.noProposal = false;
316                 this.requestor.acceptType(
317                     this.acceptedEnums[i][0],
318                     this.acceptedEnums[i][1],
319                     this.acceptedEnumsModifiers[i],
320                     false,
321                     null,
322                     this.actualSelectionStart,
323                     this.actualSelectionEnd);
324             }
325             this.acceptedEnums = null;
326             this.acceptedEnumsModifiers = null;
327             this.acceptedEnumsCount = 0;
328         }
329     }
330     private boolean checkSelection(
331         char[] source,
332         int selectionStart,
333         int selectionEnd) {
334
335         Scanner scanner = new Scanner();
336         scanner.setSource(source);
337         
338         int lastIdentifierStart = -1;
339         int lastIdentifierEnd = -1;
340         char[] lastIdentifier = null;
341         int token;
342         
343         if(selectionStart > selectionEnd){
344             int end = source.length - 1;
345             
346             // compute start position of current line
347
int currentPosition = selectionStart - 1;
348             int nextCharacterPosition = selectionStart;
349             char currentCharacter = ' ';
350             try {
351                 lineLoop: while(currentPosition > 0){
352                     
353                     if(source[currentPosition] == '\\' && source[currentPosition+1] == 'u') {
354                         int pos = currentPosition + 2;
355                         int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
356                         while (source[pos] == 'u') {
357                             pos++;
358                         }
359                         
360                         int endOfUnicode = pos + 3;
361                         if (end < endOfUnicode) {
362                             if (endOfUnicode < source.length) {
363                                 end = endOfUnicode;
364                             } else {
365                                 return false; // not enough characters to decode an unicode
366
}
367                         }
368
369                         if ((c1 = ScannerHelper.getNumericValue(source[pos++])) > 15
370                             || c1 < 0
371                             || (c2 = ScannerHelper.getNumericValue(source[pos++])) > 15
372                             || c2 < 0
373                             || (c3 = ScannerHelper.getNumericValue(source[pos++])) > 15
374                             || c3 < 0
375                             || (c4 = ScannerHelper.getNumericValue(source[pos++])) > 15
376                             || c4 < 0) {
377                             return false;
378                         } else {
379                             currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
380                             nextCharacterPosition = pos;
381                         }
382                     } else {
383                         currentCharacter = source[currentPosition];
384                         nextCharacterPosition = currentPosition+1;
385                     }
386                     
387                     switch(currentCharacter) {
388                         case '\r':
389                         case '\n':
390                         case '/':
391                         case '"':
392                         case '\'':
393                             break lineLoop;
394                     }
395                     currentPosition--;
396                 }
397             } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
398                 return false;
399             }
400             
401             // compute start and end of the last token
402
scanner.resetTo(nextCharacterPosition, end);
403             do {
404                 try {
405                     token = scanner.getNextToken();
406                 } catch (InvalidInputException e) {
407                     return false;
408                 }
409                 switch (token) {
410                     case TerminalTokens.TokenNamethis:
411                     case TerminalTokens.TokenNamesuper:
412                     case TerminalTokens.TokenNameIdentifier:
413                         if (scanner.startPosition <= selectionStart && selectionStart <= scanner.currentPosition) {
414                             if (scanner.currentPosition == scanner.eofPosition) {
415                                 int temp = scanner.eofPosition;
416                                 scanner.eofPosition = scanner.source.length;
417                                 while(scanner.getNextCharAsJavaIdentifierPart()){/*empty*/}
418                                 scanner.eofPosition = temp;
419                             }
420                             lastIdentifierStart = scanner.startPosition;
421                             lastIdentifierEnd = scanner.currentPosition - 1;
422                             lastIdentifier = scanner.getCurrentTokenSource();
423                         }
424                         break;
425                 }
426             } while (token != TerminalTokens.TokenNameEOF);
427         } else {
428             scanner.resetTo(selectionStart, selectionEnd);
429     
430             boolean expectingIdentifier = true;
431             try {
432                 do {
433                     token = scanner.getNextToken();
434
435                     switch (token) {
436                         case TerminalTokens.TokenNamethis :
437                         case TerminalTokens.TokenNamesuper :
438                         case TerminalTokens.TokenNameIdentifier :
439                             if (!expectingIdentifier)
440                                 return false;
441                             lastIdentifier = scanner.getCurrentTokenSource();
442                             lastIdentifierStart = scanner.startPosition;
443                             lastIdentifierEnd = scanner.currentPosition - 1;
444                             if(lastIdentifierEnd > selectionEnd) {
445                                 lastIdentifierEnd = selectionEnd;
446                                 lastIdentifier = CharOperation.subarray(lastIdentifier, 0,lastIdentifierEnd - lastIdentifierStart + 1);
447                             }
448     
449                             expectingIdentifier = false;
450                             break;
451                         case TerminalTokens.TokenNameDOT :
452                             if (expectingIdentifier)
453                                 return false;
454                             expectingIdentifier = true;
455                             break;
456                         case TerminalTokens.TokenNameEOF :
457                             if (expectingIdentifier)
458                                 return false;
459                             break;
460                         case TerminalTokens.TokenNameLESS :
461                             if(!checkTypeArgument(scanner))
462                                 return false;
463                             break;
464                         case TerminalTokens.TokenNameAT:
465                             if(scanner.startPosition != scanner.initialPosition)
466                                 return false;
467                             break;
468                         default :
469                             return false;
470                     }
471                 } while (token != TerminalTokens.TokenNameEOF);
472             } catch (InvalidInputException e) {
473                 return false;
474             }
475         }
476         if (lastIdentifierStart > 0) {
477             this.actualSelectionStart = lastIdentifierStart;
478             this.actualSelectionEnd = lastIdentifierEnd;
479             this.selectedIdentifier = lastIdentifier;
480             return true;
481         }
482         return false;
483     }
484     private boolean checkTypeArgument(Scanner scanner) throws InvalidInputException {
485         int depth = 1;
486         int token;
487         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
488         do {
489             token = scanner.getNextToken();
490     
491             switch(token) {
492                 case TerminalTokens.TokenNameLESS :
493                     depth++;
494                     buffer.append(scanner.getCurrentTokenSource());
495                     break;
496                 case TerminalTokens.TokenNameGREATER :
497                     depth--;
498                     buffer.append(scanner.getCurrentTokenSource());
499                     break;
500                 case TerminalTokens.TokenNameRIGHT_SHIFT :
501                     depth-=2;
502                     buffer.append(scanner.getCurrentTokenSource());
503                     break;
504                 case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT :
505                     depth-=3;
506                     buffer.append(scanner.getCurrentTokenSource());
507                     break;
508                 case TerminalTokens.TokenNameextends :
509                 case TerminalTokens.TokenNamesuper :
510                     buffer.append(' ');
511                     buffer.append(scanner.getCurrentTokenSource());
512                     buffer.append(' ');
513                     break;
514                 case TerminalTokens.TokenNameCOMMA :
515                     if(depth == 1) {
516                         int length = buffer.length();
517                         char[] typeRef = new char[length];
518                         buffer.getChars(0, length, typeRef, 0);
519                         try {
520                             Signature.createTypeSignature(typeRef, true);
521                             buffer = new StringBuffer JavaDoc();
522                         } catch(IllegalArgumentException JavaDoc e) {
523                             return false;
524                         }
525                     }
526                     break;
527                 default :
528                     buffer.append(scanner.getCurrentTokenSource());
529                     break;
530                 
531             }
532             if(depth < 0) {
533                 return false;
534             }
535         } while (depth != 0 && token != TerminalTokens.TokenNameEOF);
536         
537         if(depth == 0) {
538             int length = buffer.length() - 1;
539             char[] typeRef = new char[length];
540             buffer.getChars(0, length, typeRef, 0);
541             try {
542                 Signature.createTypeSignature(typeRef, true);
543                 return true;
544             } catch(IllegalArgumentException JavaDoc e) {
545                 return false;
546             }
547         }
548         
549         return false;
550     }
551     
552     public AssistParser getParser() {
553         return this.parser;
554     }
555
556     /*
557      * Returns whether the given binding is a local/anonymous reference binding, or if its declaring class is
558      * local.
559      */

560     private boolean isLocal(ReferenceBinding binding) {
561         if(binding instanceof ParameterizedTypeBinding) {
562             return isLocal(((ParameterizedTypeBinding)binding).genericType());
563         }
564         if (!(binding instanceof SourceTypeBinding)) return false;
565         if (binding instanceof LocalTypeBinding) return true;
566         if (binding instanceof MemberTypeBinding) {
567             return isLocal(((MemberTypeBinding)binding).enclosingType);
568         }
569         return false;
570     }
571
572     /**
573      * Ask the engine to compute the selection at the specified position
574      * of the given compilation unit.
575
576      * @param sourceUnit org.eclipse.jdt.internal.compiler.env.ICompilationUnit
577      * the source of the current compilation unit.
578      *
579      * @param selectionSourceStart int
580      * @param selectionSourceEnd int
581      * a range in the source where the selection is.
582      */

583     public void select(
584         ICompilationUnit sourceUnit,
585         int selectionSourceStart,
586         int selectionSourceEnd) {
587
588         char[] source = sourceUnit.getContents();
589         
590         if(DEBUG) {
591             System.out.print("SELECTION IN "); //$NON-NLS-1$
592
System.out.print(sourceUnit.getFileName());
593             System.out.print(" FROM "); //$NON-NLS-1$
594
System.out.print(selectionSourceStart);
595             System.out.print(" TO "); //$NON-NLS-1$
596
System.out.println(selectionSourceEnd);
597             System.out.println("SELECTION - Source :"); //$NON-NLS-1$
598
System.out.println(source);
599         }
600         if (!checkSelection(source, selectionSourceStart, selectionSourceEnd)) {
601             return;
602         }
603         if (DEBUG) {
604             System.out.print("SELECTION - Checked : \""); //$NON-NLS-1$
605
System.out.print(new String JavaDoc(source, actualSelectionStart, actualSelectionEnd-actualSelectionStart+1));
606             System.out.println('"');
607         }
608         try {
609             this.acceptedAnswer = false;
610             CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
611             CompilationUnitDeclaration parsedUnit =
612                 this.parser.dietParse(sourceUnit, result, this.actualSelectionStart, this.actualSelectionEnd);
613
614             if (parsedUnit != null) {
615                 if(DEBUG) {
616                     System.out.println("SELECTION - Diet AST :"); //$NON-NLS-1$
617
System.out.println(parsedUnit.toString());
618                 }
619                 
620                 // scan the package & import statements first
621
if (parsedUnit.currentPackage instanceof SelectionOnPackageReference) {
622                     char[][] tokens =
623                         ((SelectionOnPackageReference) parsedUnit.currentPackage).tokens;
624                     this.noProposal = false;
625                     this.requestor.acceptPackage(CharOperation.concatWith(tokens, '.'));
626                     return;
627                 }
628                 ImportReference[] imports = parsedUnit.imports;
629                 if (imports != null) {
630                     for (int i = 0, length = imports.length; i < length; i++) {
631                         ImportReference importReference = imports[i];
632                         if (importReference instanceof SelectionOnImportReference) {
633                             char[][] tokens = ((SelectionOnImportReference) importReference).tokens;
634                             this.noProposal = false;
635                             this.requestor.acceptPackage(CharOperation.concatWith(tokens, '.'));
636                             this.nameEnvironment.findTypes(CharOperation.concatWith(tokens, '.'), false, false, IJavaSearchConstants.TYPE, this);
637                             
638                           &nb