KickJava   Java API By Example, From Geeks To Geeks.

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


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.ArrayList JavaDoc;
14 import java.util.Locale JavaDoc;
15 import java.util.Map JavaDoc;
16
17 import org.eclipse.jdt.core.CompletionContext;
18 import org.eclipse.jdt.core.CompletionFlags;
19 import org.eclipse.jdt.core.CompletionProposal;
20 import org.eclipse.jdt.core.CompletionRequestor;
21 import org.eclipse.jdt.core.Flags;
22 import org.eclipse.jdt.core.IAccessRule;
23 import org.eclipse.jdt.core.IJavaProject;
24 import org.eclipse.jdt.core.IMethod;
25 import org.eclipse.jdt.core.IType;
26 import org.eclipse.jdt.core.JavaModelException;
27 import org.eclipse.jdt.core.Signature;
28 import org.eclipse.jdt.core.compiler.CategorizedProblem;
29 import org.eclipse.jdt.core.compiler.CharOperation;
30 import org.eclipse.jdt.core.compiler.IProblem;
31 import org.eclipse.jdt.core.search.IJavaSearchConstants;
32
33 import org.eclipse.jdt.internal.codeassist.complete.*;
34 import org.eclipse.jdt.internal.codeassist.impl.AssistParser;
35 import org.eclipse.jdt.internal.codeassist.impl.Engine;
36 import org.eclipse.jdt.internal.codeassist.impl.Keywords;
37 import org.eclipse.jdt.internal.compiler.CompilationResult;
38 import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
39 import org.eclipse.jdt.internal.compiler.ast.*;
40 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
41 import org.eclipse.jdt.internal.compiler.env.*;
42 import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
43 import org.eclipse.jdt.internal.compiler.lookup.*;
44 import org.eclipse.jdt.internal.compiler.parser.Scanner;
45 import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
46 import org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter;
47 import org.eclipse.jdt.internal.compiler.parser.JavadocTagConstants;
48 import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
49 import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
50 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
51 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
52 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
53 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
54 import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
55 import org.eclipse.jdt.internal.compiler.util.ObjectVector;
56 import org.eclipse.jdt.internal.core.BasicCompilationUnit;
57 import org.eclipse.jdt.internal.core.INamingRequestor;
58 import org.eclipse.jdt.internal.core.InternalNamingConventions;
59 import org.eclipse.jdt.internal.core.SourceMethod;
60 import org.eclipse.jdt.internal.core.SourceMethodElementInfo;
61 import org.eclipse.jdt.internal.core.SourceType;
62 import org.eclipse.jdt.internal.core.BinaryTypeConverter;
63 import org.eclipse.jdt.internal.core.SearchableEnvironment;
64 import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
65
66 /**
67  * This class is the entry point for source completions.
68  * It contains two public APIs used to call CodeAssist on a given source with
69  * a given environment, assisting position and storage (and possibly options).
70  */

71 public final class CompletionEngine
72     extends Engine
73     implements ISearchRequestor, TypeConstants , TerminalTokens , RelevanceConstants, SuffixConstants {
74     
75     public class CompletionProblemFactory extends DefaultProblemFactory {
76         private int lastErrorStart;
77         
78         private boolean checkProblems = false;
79         public boolean hasForbiddenProblems = false;
80         public boolean hasAllowedProblems = false;
81         
82         public CompletionProblemFactory(Locale JavaDoc loc) {
83             super(loc);
84         }
85
86         public CategorizedProblem createProblem(
87             char[] originatingFileName,
88             int problemId,
89             String JavaDoc[] problemArguments,
90             String JavaDoc[] messageArguments,
91             int severity,
92             int start,
93             int end,
94             int lineNumber,
95             int columnNumber) {
96             
97             CategorizedProblem pb = super.createProblem(
98                 originatingFileName,
99                 problemId,
100                 problemArguments,
101                 messageArguments,
102                 severity,
103                 start,
104                 end,
105                 lineNumber,
106                 columnNumber);
107             int id = pb.getID();
108             if (CompletionEngine.this.actualCompletionPosition > start
109                 && this.lastErrorStart < start
110                 && pb.isError()
111                 && (id & IProblem.Syntax) == 0
112                 && (CompletionEngine.this.fileName == null || CharOperation.equals(CompletionEngine.this.fileName, originatingFileName))) {
113                     
114                 CompletionEngine.this.problem = pb;
115                 this.lastErrorStart = start;
116             }
117             if (this.checkProblems && !this.hasForbiddenProblems) {
118                 switch (id) {
119                     case IProblem.UsingDeprecatedType:
120                         this.hasForbiddenProblems =
121                             CompletionEngine.this.options.checkDeprecation;
122                         break;
123                     case IProblem.NotVisibleType:
124                         this.hasForbiddenProblems =
125                             CompletionEngine.this.options.checkVisibility;
126                         break;
127                     case IProblem.ForbiddenReference:
128                         this.hasForbiddenProblems =
129                             CompletionEngine.this.options.checkForbiddenReference;
130                         break;
131                     case IProblem.DiscouragedReference:
132                         this.hasForbiddenProblems =
133                             CompletionEngine.this.options.checkDiscouragedReference;
134                         break;
135                     default:
136                         if ((severity & ProblemSeverities.Optional) != 0) {
137                             this.hasAllowedProblems = true;
138                         } else {
139                             this.hasForbiddenProblems = true;
140                         }
141                         
142                         break;
143                 }
144             }
145             
146             return pb;
147         }
148         
149         public void startCheckingProblems() {
150             this.checkProblems = true;
151             this.hasForbiddenProblems = false;
152             this.hasAllowedProblems = false;
153         }
154         
155         public void stopCheckingProblems() {
156             this.checkProblems = false;
157         }
158     }
159
160     private static class AcceptedType {
161         public AcceptedType(
162             char[] packageName,
163             char[] simpleTypeName,
164             char[][] enclosingTypeNames,
165             int modifiers,
166             int accessibility) {
167             this.packageName = packageName;
168             this.simpleTypeName = simpleTypeName;
169             this.enclosingTypeNames = enclosingTypeNames;
170             this.modifiers = modifiers;
171             this.accessibility = accessibility;
172         }
173         public char[] packageName;
174         public char[] simpleTypeName;
175         public char[][] enclosingTypeNames;
176         public int modifiers;
177         public int accessibility;
178         
179         public boolean mustBeQualified = false;
180         public char[] fullyQualifiedName = null;
181         public char[] qualifiedTypeName = null;
182         
183         public String JavaDoc toString() {
184             StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
185             buffer.append('{');
186             buffer.append(packageName);
187             buffer.append(',');
188             buffer.append(simpleTypeName);
189             buffer.append(',');
190             buffer.append(CharOperation.concatWith(enclosingTypeNames, '.'));
191             buffer.append('}');
192             return buffer.toString();
193         }
194     }
195     
196     public HashtableOfObject typeCache;
197     
198     public static boolean DEBUG = false;
199     public static boolean PERF = false;
200     
201     // temporary constants to quickly disabled polish features if necessary
202
public final static boolean NO_TYPE_COMPLETION_ON_EMPTY_TOKEN = false;
203     
204     private final static char[] ERROR_PATTERN = "*error*".toCharArray(); //$NON-NLS-1$
205
private final static char[] EXCEPTION_PATTERN = "*exception*".toCharArray(); //$NON-NLS-1$
206
private final static char[] SEMICOLON = new char[] { ';' };
207     
208     private final static char[] CLASS = "Class".toCharArray(); //$NON-NLS-1$
209
private final static char[] VOID = "void".toCharArray(); //$NON-NLS-1$
210
private final static char[] INT = "int".toCharArray(); //$NON-NLS-1$
211
private final static char[] INT_SIGNATURE = new char[]{Signature.C_INT};
212     private final static char[] VALUE = "value".toCharArray(); //$NON-NLS-1$
213
private final static char[] EXTENDS = "extends".toCharArray(); //$NON-NLS-1$
214
private final static char[] SUPER = "super".toCharArray(); //$NON-NLS-1$
215

216     private final static char[] VARARGS = "...".toCharArray(); //$NON-NLS-1$
217

218     private final static char[] IMPORT = "import".toCharArray(); //$NON-NLS-1$
219
private final static char[] STATIC = "static".toCharArray(); //$NON-NLS-1$
220
private final static char[] ON_DEMAND = ".*".toCharArray(); //$NON-NLS-1$
221
private final static char[] IMPORT_END = ";\n".toCharArray(); //$NON-NLS-1$
222

223     private final static char[] JAVA_LANG_OBJECT_SIGNATURE =
224         createTypeSignature(CharOperation.concatWith(JAVA_LANG, '.'), OBJECT);
225     private final static char[] JAVA_LANG_NAME =
226         CharOperation.concatWith(JAVA_LANG, '.');
227     
228     private final static int NONE = 0;
229     private final static int SUPERTYPE = 1;
230     private final static int SUBTYPE = 2;
231     
232     private final static int FIELD = 0;
233     private final static int LOCAL = 1;
234     private final static int ARGUMENT = 2;
235
236     int expectedTypesPtr = -1;
237     TypeBinding[] expectedTypes = new TypeBinding[1];
238     int expectedTypesFilter;
239     boolean hasJavaLangObjectAsExpectedType = false;
240     int uninterestingBindingsPtr = -1;
241     Binding[] uninterestingBindings = new Binding[1];
242     int forbbidenBindingsPtr = -1;
243     Binding[] forbbidenBindings = new Binding[1];
244     int forbbidenBindingsFilter;
245     
246     ImportBinding[] favoriteReferenceBindings;
247     
248     boolean assistNodeIsClass;
249     boolean assistNodeIsEnum;
250     boolean assistNodeIsException;
251     boolean assistNodeIsInterface;
252     boolean assistNodeIsAnnotation;
253     boolean assistNodeIsConstructor;
254     boolean assistNodeIsSuperType;
255     int assistNodeInJavadoc = 0;
256     boolean assistNodeCanBeSingleMemberAnnotation = false;
257     
258     long targetedElement;
259     
260     IJavaProject javaProject;
261     CompletionParser parser;
262     CompletionRequestor requestor;
263     CompletionProblemFactory problemFactory;
264     ProblemReporter problemReporter;
265     char[] source;
266     char[] completionToken;
267     char[] qualifiedCompletionToken;
268     boolean resolvingImports = false;
269     boolean resolvingStaticImports = false;
270     boolean insideQualifiedReference = false;
271     boolean noProposal = true;
272     CategorizedProblem problem = null;
273     char[] fileName = null;
274     int startPosition, actualCompletionPosition, endPosition, offset;
275     int javadocTagPosition; // Position of previous tag while completing in javadoc
276
HashtableOfObject knownPkgs = new HashtableOfObject(10);
277     HashtableOfObject knownTypes = new HashtableOfObject(10);
278     Scanner nameScanner;
279
280     /*
281         static final char[][] mainDeclarations =
282             new char[][] {
283                 "package".toCharArray(),
284                 "import".toCharArray(),
285                 "abstract".toCharArray(),
286                 "final".toCharArray(),
287                 "public".toCharArray(),
288                 "class".toCharArray(),
289                 "interface".toCharArray()};
290     
291         static final char[][] modifiers = // may want field, method, type & member type modifiers
292             new char[][] {
293                 "abstract".toCharArray(),
294                 "final".toCharArray(),
295                 "native".toCharArray(),
296                 "public".toCharArray(),
297                 "protected".toCharArray(),
298                 "private".toCharArray(),
299                 "static".toCharArray(),
300                 "strictfp".toCharArray(),
301                 "synchronized".toCharArray(),
302                 "transient".toCharArray(),
303                 "volatile".toCharArray()};
304     */

305     static final BaseTypeBinding[] BASE_TYPES = {
306         TypeBinding.BOOLEAN,
307         TypeBinding.BYTE,
308         TypeBinding.CHAR,
309         TypeBinding.DOUBLE,
310         TypeBinding.FLOAT,
311         TypeBinding.INT,
312         TypeBinding.LONG,
313         TypeBinding.SHORT,
314         TypeBinding.VOID
315     };
316     static final int BASE_TYPES_LENGTH = BASE_TYPES.length;
317     static final char[][] BASE_TYPE_NAMES = new char[BASE_TYPES_LENGTH][];
318     static {
319         for (int i=0; i<BASE_TYPES_LENGTH; i++) {
320             BASE_TYPE_NAMES[i] = BASE_TYPES[i].simpleName;
321         }
322     }
323         
324     static final char[] classField = "class".toCharArray(); //$NON-NLS-1$
325
static final char[] lengthField = "length".toCharArray(); //$NON-NLS-1$
326
static final char[] cloneMethod = "clone".toCharArray(); //$NON-NLS-1$
327
static final char[] THIS = "this".toCharArray(); //$NON-NLS-1$
328
static final char[] THROWS = "throws".toCharArray(); //$NON-NLS-1$
329

330     static InvocationSite FakeInvocationSite = new InvocationSite(){
331         public TypeBinding[] genericTypeArguments() { return null; }
332         public boolean isSuperAccess(){ return false; }
333         public boolean isTypeAccess(){ return false; }
334         public void setActualReceiverType(ReferenceBinding receiverType) {/* empty */}
335         public void setDepth(int depth){/* empty */}
336         public void setFieldIndex(int depth){/* empty */}
337         public int sourceStart() { return 0; }
338         public int sourceEnd() { return 0; }
339     };
340     
341     private ObjectVector acceptedTypes;
342     
343     /**
344      * The CompletionEngine is responsible for computing source completions.
345      *
346      * It requires a searchable name environment, which supports some
347      * specific search APIs, and a requestor to feed back the results to a UI.
348      *
349      * @param nameEnvironment org.eclipse.jdt.internal.codeassist.ISearchableNameEnvironment
350      * used to resolve type/package references and search for types/packages
351      * based on partial names.
352      *
353      * @param requestor org.eclipse.jdt.internal.codeassist.ICompletionRequestor
354      * since the engine might produce answers of various forms, the engine
355      * is associated with a requestor able to accept all possible completions.
356      *
357      * @param settings java.util.Map
358      * set of options used to configure the code assist engine.
359      */

360     public CompletionEngine(
361             SearchableEnvironment nameEnvironment,
362             CompletionRequestor requestor,
363             Map JavaDoc settings,
364             IJavaProject javaProject) {
365         super(settings);
366         this.javaProject = javaProject;
367         this.requestor = requestor;
368         this.nameEnvironment = nameEnvironment;
369         this.typeCache = new HashtableOfObject(5);
370
371         this.problemFactory = new CompletionProblemFactory(Locale.getDefault());
372         this.problemReporter = new ProblemReporter(
373                 DefaultErrorHandlingPolicies.proceedWithAllProblems(),
374                 this.compilerOptions,
375                 problemFactory);
376         this.lookupEnvironment =
377             new LookupEnvironment(this, this.compilerOptions, this.problemReporter, nameEnvironment);
378         this.parser =
379             new CompletionParser(this.problemReporter);
380         this.nameScanner =
381             new Scanner(
382                 false /*comment*/,
383                 false /*whitespace*/,
384                 false /*nls*/,
385                 this.compilerOptions.sourceLevel,
386                 null /*taskTags*/,
387                 null/*taskPriorities*/,
388                 true/*taskCaseSensitive*/);
389     }
390
391     /**
392      * One result of the search consists of a new type.
393      *
394      * NOTE - All package and type names are presented in their readable form:
395      * Package names are in the form "a.b.c".
396      * Nested type names are in the qualified form "A.I".
397      * The default package is represented by an empty array.
398      */

399     public void acceptType(
400         char[] packageName,
401         char[] simpleTypeName,
402         char[][] enclosingTypeNames,
403         int modifiers,
404         AccessRestriction accessRestriction) {
405
406         if (this.options.checkDeprecation && (modifiers & ClassFileConstants.AccDeprecated) != 0) return;
407         
408         if (this.options.checkVisibility) {
409             if((modifiers & ClassFileConstants.AccPublic) == 0) {
410                 if((modifiers & ClassFileConstants.AccPrivate) != 0) return;
411                 
412                 char[] currentPackage = CharOperation.concatWith(this.unitScope.fPackage.compoundName, '.');
413                 if(!CharOperation.equals(packageName, currentPackage)) return;
414             }
415         }
416         
417         int accessibility = IAccessRule.K_ACCESSIBLE;
418         if(accessRestriction != null) {
419             switch (accessRestriction.getProblemId()) {
420                 case IProblem.ForbiddenReference:
421                     if (this.options.checkForbiddenReference) {
422                         return;
423                     }
424                     accessibility = IAccessRule.K_NON_ACCESSIBLE;
425                     break;
426                 case IProblem.DiscouragedReference:
427                     if (this.options.checkDiscouragedReference) {
428                         return;
429                     }
430                     accessibility = IAccessRule.K_DISCOURAGED;
431                     break;
432             }
433         }
434         
435         if(acceptedTypes == null) {
436             acceptedTypes = new ObjectVector();
437         }
438         acceptedTypes.add(new AcceptedType(packageName, simpleTypeName, enclosingTypeNames, modifiers, accessibility));
439     }
440     
441     private void acceptTypes(Scope scope) {
442         if(this.acceptedTypes == null) return;
443         
444         int length = this.acceptedTypes.size();
445         
446         if(length == 0) return;
447         
448         HashtableOfObject onDemandFound = new HashtableOfObject();
449         
450         next : for (int i = 0; i < length; i++) {
451             AcceptedType acceptedType = (AcceptedType)this.acceptedTypes.elementAt(i);
452             char[] packageName = acceptedType.packageName;
453             char[] simpleTypeName = acceptedType.simpleTypeName;
454             char[][] enclosingTypeNames = acceptedType.enclosingTypeNames;
455             int modifiers = acceptedType.modifiers;
456             int accessibility = acceptedType.accessibility;
457             
458             char[] typeName;
459             char[] flatEnclosingTypeNames;
460             if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
461                 flatEnclosingTypeNames = null;
462                 typeName = simpleTypeName;
463             } else {
464                 flatEnclosingTypeNames = CharOperation.concatWith(acceptedType.enclosingTypeNames, '.');
465                 typeName = CharOperation.concat(flatEnclosingTypeNames, simpleTypeName, '.');
466             }
467             char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
468             
469             if (this.knownTypes.containsKey(fullyQualifiedName)) continue next;
470     
471             this.knownTypes.put(fullyQualifiedName, this);
472             
473             if (this.resolvingImports) {
474                 char[] completionName;
475                 
476                 if(this.resolvingStaticImports) {
477                     if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
478                         completionName = CharOperation.concat(fullyQualifiedName, new char[] { '.' });
479                     } else if ((modifiers & ClassFileConstants.AccStatic) == 0) {
480                         continue next;
481                     } else {
482                         completionName = CharOperation.concat(fullyQualifiedName, new char[] { ';' });
483                     }
484                 } else {
485                     completionName = CharOperation.concat(fullyQualifiedName, new char[] { ';' });
486                 }
487                 
488                 int relevance = computeBaseRelevance();
489                 relevance += computeRelevanceForResolution();
490                 relevance += computeRelevanceForInterestingProposal();
491                 relevance += computeRelevanceForRestrictions(accessibility);
492                 if(insideQualifiedReference) {
493                     relevance += computeRelevanceForCaseMatching(this.completionToken, fullyQualifiedName);
494                 } else {
495                     relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
496                 }
497                 
498                 this.noProposal = false;
499                 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
500                     createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance);
501                 }
502             } else {
503                 if(!this.importCachesInitialized) {
504                     this.initializeImportCaches();
505                 }
506             
507                 for (int j = 0; j < this.importCacheCount; j++) {
508                     char[][] importName = this.importsCache[j];
509                     if(CharOperation.equals(typeName, importName[0])) {
510                         proposeType(
511                                 packageName,
512                                 simpleTypeName,
513                                 modifiers,
514                                 accessibility,
515                                 typeName,
516                                 fullyQualifiedName,
517                                 !CharOperation.equals(fullyQualifiedName, importName[1]),
518                                 scope);
519                         continue next;
520                     }
521                 }
522                 
523                 
524                 if ((enclosingTypeNames == null || enclosingTypeNames.length == 0 ) && CharOperation.equals(this.currentPackageName, packageName)) {
525                     proposeType(
526                             packageName,
527                             simpleTypeName,
528                             modifiers,
529                             accessibility,
530                             typeName,
531                             fullyQualifiedName,
532                             false,
533                             scope);
534                     continue next;
535                 } else {
536                     char[] fullyQualifiedEnclosingTypeOrPackageName = null;
537             
538                     AcceptedType foundType = null;
539                     if((foundType = (AcceptedType)onDemandFound.get(simpleTypeName)) == null) {
540                         for (int j = 0; j < this.onDemandImportCacheCount; j++) {
541                             ImportBinding importBinding = this.onDemandImportsCache[j];
542
543                             char[][] importName = importBinding.compoundName;
544                             char[] importFlatName = CharOperation.concatWith(importName, '.');
545                         
546                             if(fullyQualifiedEnclosingTypeOrPackageName == null) {
547                                 if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
548                                     fullyQualifiedEnclosingTypeOrPackageName =
549                                         CharOperation.concat(
550                                                 packageName,
551                                                 flatEnclosingTypeNames,
552                                                 '.');
553                                 } else {
554                                     fullyQualifiedEnclosingTypeOrPackageName =
555                                         packageName;
556                                 }
557                             }
558                             if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
559                                 if(importBinding.isStatic()) {
560                                     if((modifiers & ClassFileConstants.AccStatic) != 0) {
561                                         acceptedType.qualifiedTypeName = typeName;
562                                         acceptedType.fullyQualifiedName = fullyQualifiedName;
563                                         onDemandFound.put(
564                                                 simpleTypeName,
565                                                 acceptedType);
566                                         continue next;
567                                     }
568                                 } else {
569                                     acceptedType.qualifiedTypeName = typeName;
570                                     acceptedType.fullyQualifiedName = fullyQualifiedName;
571                                     onDemandFound.put(
572                                             simpleTypeName,
573                                             acceptedType);
574                                     continue next;
575                                 }
576                             }
577                         }
578                     } else if(!foundType.mustBeQualified){
579                         done : for (int j = 0; j < this.onDemandImportCacheCount; j++) {
580                             ImportBinding importBinding = this.onDemandImportsCache[j];
581
582                             char[][] importName = importBinding.compoundName;
583                             char[] importFlatName = CharOperation.concatWith(importName, '.');
584                         
585                             if(fullyQualifiedEnclosingTypeOrPackageName == null) {
586                                 if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
587                                     fullyQualifiedEnclosingTypeOrPackageName =
588                                         CharOperation.concat(
589                                                 packageName,
590                                                 flatEnclosingTypeNames,
591                                                 '.');
592                                 } else {
593                                     fullyQualifiedEnclosingTypeOrPackageName =
594                                         packageName;
595                                 }
596                             }
597                             if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
598                                 if(importBinding.isStatic()) {
599                                     if((modifiers & ClassFileConstants.AccStatic) != 0) {
600                                         foundType.mustBeQualified = true;
601                                         break done;
602                                     }
603                                 } else {
604                                     foundType.mustBeQualified = true;
605                                     break done;
606                                 }
607                             }
608                         }
609                     }
610                     proposeType(
611                             packageName,
612                             simpleTypeName,
613                             modifiers,
614                             accessibility,
615                             typeName,
616                             fullyQualifiedName,
617                             true,
618                             scope);
619                 }
620             }
621         }
622         char[][] keys = onDemandFound.keyTable;
623         Object JavaDoc[] values = onDemandFound.valueTable;
624         int max = keys.length;
625         for (int i = 0; i < max; i++) {
626             if(keys[i] != null) {
627                 AcceptedType value = (AcceptedType) values[i];
628                 if(value != null) {
629                     proposeType(
630                             value.packageName,
631                             value.simpleTypeName,
632                             value.modifiers,
633                             value.accessibility,
634                             value.qualifiedTypeName,
635                             value.fullyQualifiedName,
636                             value.mustBeQualified,
637                             scope);
638                 }
639             }
640         }
641         this.acceptedTypes = null; // reset
642
}
643     
644     public void acceptUnresolvedName(char[] name) {
645         int relevance = computeBaseRelevance();
646         relevance += computeRelevanceForResolution(false);
647         relevance += computeRelevanceForInterestingProposal();
648         relevance += computeRelevanceForCaseMatching(completionToken, name);
649         relevance += computeRelevanceForQualification(false);
650         relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for local variable
651
CompletionEngine.this.noProposal = false;
652         if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
653             CompletionProposal proposal = CompletionEngine.this.createProposal(CompletionProposal.LOCAL_VARIABLE_REF, CompletionEngine.this.actualCompletionPosition);
654             proposal.setSignature(JAVA_LANG_OBJECT_SIGNATURE);
655             proposal.setPackageName(JAVA_LANG_NAME);
656             proposal.setTypeName(OBJECT);
657             proposal.setName(name);
658             proposal.setCompletion(name);
659             proposal.setFlags(Flags.AccDefault);
660             proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
661             proposal.setRelevance(relevance);
662             CompletionEngine.this.requestor.accept(proposal);
663             if(DEBUG) {
664                 CompletionEngine.this.printDebug(proposal);
665             }
666         }
667     }
668
669     // this code is derived from MethodBinding#areParametersCompatibleWith(TypeBinding[])
670
private final boolean areParametersCompatibleWith(TypeBinding[] parameters, TypeBinding[] arguments, boolean isVarargs) {
671         int paramLength = parameters.length;
672         int argLength = arguments.length;
673         int lastIndex = argLength;
674         if (isVarargs) {
675             lastIndex = paramLength - 1;
676             if (paramLength == argLength) { // accept X[] but not X or X[][]
677
TypeBinding varArgType = parameters[lastIndex]; // is an ArrayBinding by definition
678
TypeBinding lastArgument = arguments[lastIndex];
679                 if (varArgType != lastArgument && !lastArgument.isCompatibleWith(varArgType))
680                     return false;
681             } else if (paramLength < argLength) { // all remainig argument types must be compatible with the elementsType of varArgType
682
TypeBinding varArgType = ((ArrayBinding) parameters[lastIndex]).elementsType();
683                 for (int i = lastIndex; i < argLength; i++)
684                     if (varArgType != arguments[i] && !arguments[i].isCompatibleWith(varArgType))
685                         return false;
686             } else if (lastIndex != argLength) { // can call foo(int i, X ... x) with foo(1) but NOT foo();
687
return false;
688             }
689             // now compare standard arguments from 0 to lastIndex
690
} else {
691             if(paramLength != argLength)
692                 return false;
693         }
694         for (int i = 0; i < lastIndex; i++)
695             if (parameters[i] != arguments[i] && !arguments[i].isCompatibleWith(parameters[i]))
696                 return false;
697         return true;
698     }
699     
700     private void proposeType(char[] packageName, char[] simpleTypeName, int modifiers, int accessibility, char[] typeName, char[] fullyQualifiedName, boolean isQualified, Scope scope) {
701         char[] completionName = fullyQualifiedName;
702         if(isQualified) {
703             if (packageName == null || packageName.length == 0)
704                 if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
705                     return; // ignore types from the default package from outside it
706
} else {
707             completionName = simpleTypeName;
708         }
709         
710         TypeBinding guessedType = null;
711         if ((modifiers & ClassFileConstants.AccAnnotation) != 0 &&
712                 this.assistNodeIsAnnotation &&
713                 (this.targetedElement & TagBits.AnnotationTargetMASK) != 0) {
714             char[][] cn = CharOperation.splitOn('.', fullyQualifiedName);
715             
716             TypeReference ref;
717             if (cn.length == 1) {
718                 ref = new SingleTypeReference(simpleTypeName, 0);
719             } else {
720                 ref = new QualifiedTypeReference(cn,new long[cn.length]);
721             }
722             
723             switch (scope.kind) {
724                 case Scope.METHOD_SCOPE :
725                 case Scope.BLOCK_SCOPE :
726                     guessedType = ref.resolveType((BlockScope)scope);
727                     break;
728                 case Scope.CLASS_SCOPE :
729                     guessedType = ref.resolveType((ClassScope)scope);
730                     break;
731             }
732             
733             if (guessedType == null || !guessedType.isValidBinding()) return;
734             
735             if (!hasPossibleAnnotationTarget(guessedType, scope)) return;
736         }
737
738         int relevance = computeBaseRelevance();
739         relevance += computeRelevanceForResolution();
740         relevance += computeRelevanceForInterestingProposal();
741         relevance += computeRelevanceForRestrictions(accessibility);
742         relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
743         relevance += computeRelevanceForExpectingType(packageName, simpleTypeName);
744         relevance += computeRelevanceForQualification(isQualified);
745         
746         int kind = modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation);
747         switch (kind) {
748             case ClassFileConstants.AccAnnotation:
749             case ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface:
750                 relevance += computeRelevanceForAnnotation();
751                 if (guessedType != null) relevance += computeRelevanceForAnnotationTarget(guessedType);
752                 relevance += computeRelevanceForInterface();
753                 break;
754             case ClassFileConstants.AccEnum:
755                 relevance += computeRelevanceForEnum();
756                 break;
757             case ClassFileConstants.AccInterface:
758                 relevance += computeRelevanceForInterface();
759                 break;
760             default:
761                 relevance += computeRelevanceForClass();
762                 relevance += computeRelevanceForException(simpleTypeName);
763                 break;
764         }
765         
766         this.noProposal = false;
767         if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
768             createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance);
769         }
770     }
771
772     /**
773      * One result of the search consists of a new package.
774      *
775      * NOTE - All package names are presented in their readable form:
776      * Package names are in the form "a.b.c".
777      * The default package is represented by an empty array.
778      */

779     public void acceptPackage(char[] packageName) {
780
781         if (this.knownPkgs.containsKey(packageName)) return;
782
783         this.knownPkgs.put(packageName, this);
784         
785         char[] completion;
786         if(this.resolvingImports) {
787             if(this.resolvingStaticImports) {
788                 completion = CharOperation.concat(packageName, new char[] { '.' });
789             } else {
790                 completion = CharOperation.concat(packageName, new char[] { '.', '*', ';' });
791             }
792         } else {
793             completion = packageName;
794         }
795                                 
796         int relevance = computeBaseRelevance();
797         relevance += computeRelevanceForResolution();
798         relevance += computeRelevanceForInterestingProposal();
799         relevance += computeRelevanceForCaseMatching(this.qualifiedCompletionToken == null ? this.completionToken : this.qualifiedCompletionToken, packageName);
800         if(!this.resolvingImports) {
801             relevance += computeRelevanceForQualification(true);
802         }
803         relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
804         
805         this.noProposal = false;
806         if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
807             CompletionProposal proposal = this.createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition);
808             proposal.setDeclarationSignature(packageName);
809             proposal.setPackageName(packageName);
810             proposal.setCompletion(completion);
811             proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
812             proposal.setRelevance(relevance);
813             this.requestor.accept(proposal);
814             if(DEBUG) {
815                 this.printDebug(proposal);
816             }
817         }
818     }
819         
820     private void buildContext(
821             ASTNode astNode,
822             ASTNode astNodeParent,
823             Binding qualifiedBinding,
824             Scope scope) {
825         CompletionContext context = new CompletionContext();
826         
827         // build expected types context
828
if (this.expectedTypesPtr > -1) {
829             int length = this.expectedTypesPtr + 1;
830             char[][] expTypes = new char[length][];
831             char[][] expKeys = new char[length][];
832             for (int i = 0; i < length; i++) {
833                 expTypes[i] = getSignature(this.expectedTypes[i]);
834                 expKeys[i] = this.expectedTypes[i].computeUniqueKey();
835             }
836             context.setExpectedTypesSignatures(expTypes);
837             context.setExpectedTypesKeys(expKeys);
838         }
839         
840         context.setOffset(this.actualCompletionPosition + 1 - this.offset);
841         
842         // Set javadoc info
843
if (astNode instanceof CompletionOnJavadoc) {
844             this.assistNodeInJavadoc = ((CompletionOnJavadoc)astNode).getCompletionFlags();
845             context.setJavadoc(this.assistNodeInJavadoc);
846         }
847         
848         if (!(astNode instanceof CompletionOnJavadoc)) {
849             CompletionScanner scanner = (CompletionScanner)this.parser.scanner;
850             context.setToken(scanner.completionIdentifier);
851             context.setTokenRange(
852                     scanner.completedIdentifierStart - this.offset,
853                     scanner.completedIdentifierEnd - this.offset,
854                     scanner.endOfEmptyToken - this.offset);
855         } else if(astNode instanceof CompletionOnJavadocTag) {
856             CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode;
857             context.setToken(CharOperation.concat(new char[]{'@'}, javadocTag.token));
858             context.setTokenRange(
859                     javadocTag.tagSourceStart - this.offset,
860                     javadocTag.tagSourceEnd - this.offset,
861                     ((CompletionScanner)this.parser.javadocParser.scanner).endOfEmptyToken - this.offset);
862         } else {
863             CompletionScanner scanner = (CompletionScanner)this.parser.javadocParser.scanner;
864             context.setToken(scanner.completionIdentifier);
865             context.setTokenRange(
866                     scanner.completedIdentifierStart - this.offset,
867                     scanner.completedIdentifierEnd - this.offset,
868                     scanner.endOfEmptyToken - this.offset);
869         }
870         
871         if(astNode instanceof CompletionOnStringLiteral) {
872             context.setTokenKind(CompletionContext.TOKEN_KIND_STRING_LITERAL);
873         } else {
874             context.setTokenKind(CompletionContext.TOKEN_KIND_NAME);
875         }
876         
877         if(DEBUG) {
878             System.out.println(context.toString());
879         }
880         this.requestor.acceptContext(context);
881     }
882     
883     private boolean complete(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope, boolean insideTypeAnnotation) {
884
885         setSourceRange(astNode.sourceStart, astNode.sourceEnd);
886
887         scope = computeForbiddenBindings(astNode, astNodeParent, scope);
888         computeUninterestingBindings(astNodeParent, scope);
889         if(astNodeParent != null) {
890             if(!isValidParent(astNodeParent, astNode, scope)) return false;
891             computeExpectedTypes(astNodeParent, astNode, scope);
892         }
893         
894         buildContext(astNode, astNodeParent, qualifiedBinding, scope);
895         
896         if (astNode instanceof CompletionOnFieldType) {
897
898             CompletionOnFieldType field = (CompletionOnFieldType) astNode;
899             CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) field.type;
900             this.completionToken = type.token;
901             setSourceRange(type.sourceStart, type.sourceEnd);
902             
903             findTypesAndPackages(this.completionToken, scope, new ObjectVector());
904             if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
905                 findKeywordsForMember(this.completionToken, field.modifiers);
906             }
907             
908             if (!field.isLocalVariable && field.modifiers == ClassFileConstants.AccDefault) {
909                 SourceTypeBinding enclosingType = scope.enclosingSourceType();
910                 if (!enclosingType.isAnnotationType()) {
911                     if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
912                         findMethods(this.completionToken,null,null,enclosingType,scope,new ObjectVector(),false,false,true,null,null,false,false,true,null, null, null, false);
913                     }
914                     if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
915                         proposeNewMethod(this.completionToken, enclosingType);
916                     }
917                 }
918             }
919         } else if (astNode instanceof CompletionOnMethodReturnType) {
920
921             CompletionOnMethodReturnType method = (CompletionOnMethodReturnType) astNode;
922             SingleTypeReference type = (CompletionOnSingleTypeReference) method.returnType;
923             this.completionToken = type.token;
924             setSourceRange(type.sourceStart, type.sourceEnd);
925             findTypesAndPackages(this.completionToken, scope.parent, new ObjectVector());
926             if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
927                 findKeywordsForMember(this.completionToken, method.modifiers);
928             }
929
930             if (method.modifiers == ClassFileConstants.AccDefault) {
931                 SourceTypeBinding enclosingType = scope.enclosingSourceType();
932                 if (!enclosingType.isAnnotationType()) {
933                     if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
934                         findMethods(this.completionToken,null,null,scope.enclosingSourceType(),scope,new ObjectVector(),false,false,true,null,null,false,false,true,null, null, null, false);
935                     }
936                     if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
937                         proposeNewMethod(this.completionToken, scope.enclosingSourceType());
938                     }
939                 }
940             }
941         } else if (astNode instanceof CompletionOnSingleNameReference) {
942
943             CompletionOnSingleNameReference singleNameReference = (CompletionOnSingleNameReference) astNode;
944             this.completionToken = singleNameReference.token;
945             SwitchStatement switchStatement = astNodeParent instanceof SwitchStatement ? (SwitchStatement) astNodeParent : null;
946             if (switchStatement != null
947                     && switchStatement.expression.resolvedType != null
948                     && switchStatement.expression.resolvedType.isEnum()) {
949                 if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
950                     this.assistNodeIsEnum = true;
951                     this.findEnumConstant(this.completionToken, (SwitchStatement) astNodeParent);
952                 }
953             } else if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
954                 findTypesAndPackages(this.completionToken, scope, new ObjectVector());
955             } else {
956                 if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
957                     char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, singleNameReference);
958                     
959                     findUnresolvedReference(
960                             singleNameReference.sourceStart,
961                             singleNameReference.sourceEnd,
962                             (BlockScope)scope,
963                             alreadyDefinedName);
964                 }
965                 findVariablesAndMethods(
966                     this.completionToken,
967                     scope,
968                     singleNameReference,
969                     scope,
970                     insideTypeAnnotation,
971                     singleNameReference.isInsideAnnotationAttribute);
972                 // can be the start of a qualified type name
973
findTypesAndPackages(this.completionToken, scope, new ObjectVector());
974                 if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
975                     if (this.completionToken != null && this.completionToken.length != 0) {
976                         findKeywords(this.completionToken, singleNameReference.possibleKeywords, false, false);
977                     } else {
978                         findTrueOrFalseKeywords(singleNameReference.possibleKeywords);
979                     }
980                 }
981                 if (singleNameReference.canBeExplicitConstructor && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)){
982                     if (CharOperation.prefixEquals(this.completionToken, Keywords.THIS, false)) {
983                         ReferenceBinding ref = scope.enclosingSourceType();
984                         findExplicitConstructors(Keywords.THIS, ref, (MethodScope)scope, singleNameReference);
985                     } else if (CharOperation.prefixEquals(this.completionToken, Keywords.SUPER, false)) {
986                         ReferenceBinding ref = scope.enclosingSourceType();
987                         findExplicitConstructors(Keywords.SUPER, ref.superclass(), (MethodScope)scope, singleNameReference);
988                     }
989                 }
990             }
991
992         } else if (astNode instanceof CompletionOnSingleTypeReference) {
993
994             CompletionOnSingleTypeReference singleRef = (CompletionOnSingleTypeReference) astNode;
995             
996             this.completionToken = singleRef.token;
997
998             this.assistNodeIsClass = singleRef.isClass();
999             this.assistNodeIsException = singleRef.isException();
1000            this.assistNodeIsInterface = singleRef.isInterface();
1001            this.assistNodeIsConstructor = singleRef.isConstructorType;
1002            this.assistNodeIsSuperType = singleRef.isSuperType();
1003            
1004            // can be the start of a qualified type name
1005
if (qualifiedBinding == null) {
1006                if (this.completionToken.length == 0 &&
1007                        (astNodeParent instanceof ParameterizedSingleTypeReference ||
1008                                astNodeParent instanceof ParameterizedQualifiedTypeReference)) {
1009                    this.setSourceRange(astNode.sourceStart, astNode.sourceStart - 1, false);
1010                    
1011                    findParameterizedType((TypeReference)astNodeParent, scope);
1012                } else {
1013                    ObjectVector typesFound = new ObjectVector();
1014                    if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
1015                        findExceptionFromTryStatement(
1016                                this.completionToken,
1017                                null,
1018                                scope.enclosingSourceType(),
1019                                (BlockScope)scope,
1020                                typesFound);
1021                    }
1022                    findTypesAndPackages(this.completionToken, scope, typesFound);
1023                }
1024            } else if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
1025                findMemberTypes(
1026                    this.completionToken,
1027                    (ReferenceBinding) qualifiedBinding,
1028                    scope,
1029                    scope.enclosingSourceType(),
1030                    false,
1031                    false,
1032                    false,
1033                    false,
1034                    !this.assistNodeIsConstructor,
1035                    null,
1036                    new ObjectVector());
1037            }
1038        } else if (astNode instanceof CompletionOnQualifiedNameReference) {
1039
1040            this.insideQualifiedReference = true;
1041            CompletionOnQualifiedNameReference ref =
1042                (CompletionOnQualifiedNameReference) astNode;
1043            this.completionToken = ref.completionIdentifier;
1044            long completionPosition = ref.sourcePositions[ref.sourcePositions.length - 1];
1045
1046            if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
1047                setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
1048                // complete field members with missing fields type
1049
// class X {
1050
// Missing f;
1051
// void foo() {
1052
// f.|
1053
// }
1054
// }
1055
if (this.assistNodeInJavadoc == 0 &&
1056                        (this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
1057                                this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
1058                    if(ref.tokens.length == 1) {
1059                        findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation);
1060                    }
1061                }
1062            } else if (qualifiedBinding instanceof VariableBinding) {
1063                setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
1064                TypeBinding receiverType = ((VariableBinding) qualifiedBinding).type;
1065                if (receiverType != null) {
1066                    findFieldsAndMethods(this.completionToken, receiverType.capture(scope, ref.sourceEnd), scope, ref, scope,false,false, null, null, null, false);
1067                } else if (this.assistNodeInJavadoc == 0 &&
1068                        (this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
1069                                this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
1070                    boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
1071                    boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);
1072                    if (proposeField || proposeMethod) {
1073                        if (qualifiedBinding instanceof LocalVariableBinding) {
1074                            // complete local variable members with missing variables type
1075
// class X {
1076
// void foo() {
1077
// Missing f;
1078
// f.|
1079
// }
1080
// }
1081
LocalVariableBinding localVariableBinding = (LocalVariableBinding) qualifiedBinding;
1082                            
1083                            findFieldsAndMethodsFromMissingType(
1084                                    this.completionToken,
1085                                    localVariableBinding.declaration.type,
1086                                    localVariableBinding.declaringScope,
1087                                    ref,
1088                                    scope);
1089                        }
1090                    }
1091                }
1092
1093            } else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
1094                boolean isInsideAnnotationAttribute = ref.isInsideAnnotationAttribute;
1095                ReferenceBinding receiverType = (ReferenceBinding) qualifiedBinding;
1096                setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
1097
1098                if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
1099                    findMemberTypes(
1100                            this.completionToken,
1101                            receiverType,
1102                            scope,
1103                            scope.enclosingSourceType(),
1104                            false,
1105                            true,
1106                            new ObjectVector());
1107                }
1108                if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
1109                    findClassField(this.completionToken, (TypeBinding) qualifiedBinding, scope);
1110                }
1111                
1112                MethodScope methodScope = null;
1113                if (!isInsideAnnotationAttribute &&
1114                        !this.requestor.isIgnored(CompletionProposal.KEYWORD) &&
1115                        ((scope instanceof MethodScope && !((MethodScope)scope).isStatic)
1116                        || ((methodScope = scope.enclosingMethodScope()) != null && !methodScope.isStatic))) {
1117                    if (this.completionToken.length > 0) {
1118                        findKeywords(this.completionToken, new char[][]{Keywords.THIS}, false, true);
1119                    } else {
1120                        int relevance = computeBaseRelevance();
1121                        relevance += computeRelevanceForResolution();
1122                        relevance += computeRelevanceForInterestingProposal();
1123                        relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.THIS);
1124                        relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
1125
relevance += R_NON_INHERITED;
1126                        
1127                        this.noProposal = false;
1128                        if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1129                            CompletionProposal proposal = this.createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
1130                            proposal.setName(Keywords.THIS);
1131                            proposal.setCompletion(Keywords.THIS);
1132                            proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
1133                            proposal.setRelevance(relevance);
1134                            this.requestor.accept(proposal);
1135                            if (DEBUG) {
1136                                this.printDebug(proposal);
1137                            }
1138                        }
1139                    }
1140                }
1141
1142                if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
1143                    findFields(
1144                        this.completionToken,
1145                        receiverType,
1146                        scope,
1147                        new ObjectVector(),
1148                        new ObjectVector(),
1149                        true,
1150                        ref,
1151                        scope,
1152                        false,
1153                        false,
1154                        null,
1155                        null,
1156                        null,
1157                        false);
1158                }
1159
1160                if (!isInsideAnnotationAttribute && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1161                    findMethods(
1162                        this.completionToken,
1163                        null,
1164                        null,
1165                        receiverType,
1166                        scope,
1167                        new ObjectVector(),
1168                        true,
1169                        false,
1170                        false,
1171                        ref,
1172                        scope,
1173                        false,
1174                        false,
1175                        false,
1176                        null,
1177                        null,
1178                        null,
1179                        false);
1180                }
1181
1182            } else if (qualifiedBinding instanceof PackageBinding) {
1183
1184                setSourceRange(astNode.sourceStart, (int) completionPosition);
1185                // replace to the end of the completion identifier
1186
findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
1187            }
1188        } else if (astNode instanceof CompletionOnQualifiedTypeReference) {
1189
1190            this.insideQualifiedReference = true;
1191            
1192            CompletionOnQualifiedTypeReference ref =
1193                (CompletionOnQualifiedTypeReference) astNode;
1194            
1195            this.assistNodeIsClass = ref.isClass();
1196            this.assistNodeIsException = ref.isException();
1197            this.assistNodeIsInterface = ref.isInterface();
1198            this.assistNodeIsSuperType = ref.isSuperType();
1199            
1200            this.completionToken = ref.completionIdentifier;
1201            long completionPosition = ref.sourcePositions[ref.tokens.length];
1202
1203            // get the source positions of the completion identifier
1204
if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
1205                if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
1206                    setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
1207                    
1208                    ObjectVector typesFound = new ObjectVector();
1209                    
1210                    if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
1211                        findExceptionFromTryStatement(
1212                                this.completionToken,
1213                                (ReferenceBinding)qualifiedBinding,
1214                                scope.enclosingSourceType(),
1215                                (BlockScope)scope,
1216                                typesFound);
1217                    }
1218                    
1219                    findMemberTypes(
1220                        this.completionToken,
1221                        (ReferenceBinding) qualifiedBinding,
1222                        scope,
1223                        scope.enclosingSourceType(),
1224                        false,
1225                        false,
1226                        typesFound);
1227                }
1228            } else if (qualifiedBinding instanceof PackageBinding) {
1229
1230                setSourceRange(astNode.sourceStart, (int) completionPosition);
1231                // replace to the end of the completion identifier
1232
findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
1233            }
1234        } else if (astNode instanceof CompletionOnMemberAccess) {
1235            this.insideQualifiedReference = true;
1236            CompletionOnMemberAccess access = (CompletionOnMemberAccess) astNode;
1237            long completionPosition = access.nameSourcePosition;
1238            setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
1239
1240            this.completionToken = access.token;
1241            
1242            if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
1243                // complete method members with missing return type
1244
// class X {
1245
// Missing f() {return null;}
1246
// void foo() {
1247
// f().|
1248
// }
1249
// }
1250
if (this.assistNodeInJavadoc == 0 &&
1251                        (this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
1252                                this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
1253                    ProblemMethodBinding problemMethodBinding = (ProblemMethodBinding) qualifiedBinding;
1254                    findFieldsAndMethodsFromMissingReturnType(
1255                            problemMethodBinding.selector,
1256                            problemMethodBinding.parameters,
1257                            scope,
1258                            access,
1259                            insideTypeAnnotation);
1260                }
1261            } else {
1262                if (!access.isInsideAnnotation) {
1263                    if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1264                        findKeywords(this.completionToken, new char[][]{Keywords.NEW}, false, false);
1265                    }
1266                    
1267                    findFieldsAndMethods(
1268                        this.completionToken,
1269                        ((TypeBinding) qualifiedBinding).capture(scope, access.receiver.sourceEnd),
1270                        scope,
1271                        access,
1272                        scope,
1273                        false,
1274                        access.receiver instanceof SuperReference,
1275                        null,
1276                        null,
1277                        null,
1278                        false);
1279                }
1280            }
1281
1282        } else if (astNode instanceof CompletionOnMessageSend) {
1283            setSourceRange(astNode.sourceStart, astNode.sourceEnd, false);
1284            
1285            CompletionOnMessageSend messageSend = (CompletionOnMessageSend) astNode;
1286            TypeBinding[] argTypes = computeTypes(messageSend.arguments);
1287            this.completionToken = messageSend.selector;
1288            if (qualifiedBinding == null) {
1289                if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1290                    findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope);
1291                }
1292            } else if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1293                findMethods(
1294                    this.completionToken,
1295                    null,
1296                    argTypes,
1297                    (ReferenceBinding)((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
1298                    scope,
1299                    new ObjectVector(),
1300                    false,
1301                    true,
1302                    false,
1303                    messageSend,
1304                    scope,
1305                    false,
1306                    messageSend.receiver instanceof SuperReference,
1307                    false,
1308                    null,
1309                    null,
1310                    null,
1311                    false);
1312            }
1313        } else if (astNode instanceof CompletionOnExplicitConstructorCall) {
1314            if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1315                setSourceRange(astNode.sourceStart, astNode.sourceEnd, false);
1316                
1317                CompletionOnExplicitConstructorCall constructorCall =
1318                    (CompletionOnExplicitConstructorCall) astNode;
1319                TypeBinding[] argTypes = computeTypes(constructorCall.arguments);
1320                findConstructors(
1321                    (ReferenceBinding) qualifiedBinding,
1322                    argTypes,
1323                    scope,
1324                    constructorCall,
1325                    false);
1326                                    }
1327        } else if (astNode instanceof CompletionOnQualifiedAllocationExpression) {
1328            setSourceRange(astNode.sourceStart, astNode.sourceEnd, false);
1329            
1330            CompletionOnQualifiedAllocationExpression allocExpression =
1331                (CompletionOnQualifiedAllocationExpression) astNode;
1332            TypeBinding[] argTypes = computeTypes(allocExpression.arguments);
1333            
1334            ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
1335            if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
1336                    && ref.isClass()
1337                    && !ref.isAbstract()) {
1338                    findConstructors(
1339                        ref,
1340                        argTypes,
1341                        scope,
1342                        allocExpression,
1343                        false);
1344            }
1345            if (!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)
1346                    && !ref.isFinal()
1347                    && !ref.isEnum()){
1348                findAnonymousType(
1349                    ref,
1350                    argTypes,
1351                    scope,
1352                    allocExpression);
1353            }
1354        } else if (astNode instanceof CompletionOnClassLiteralAccess) {
1355            if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
1356                CompletionOnClassLiteralAccess access = (CompletionOnClassLiteralAccess) astNode;
1357                setSourceRange(access.classStart, access.sourceEnd);
1358
1359                this.completionToken = access.completionIdentifier;
1360
1361                findClassField(this.completionToken, (TypeBinding) qualifiedBinding, scope);
1362            }
1363        } else if (astNode instanceof CompletionOnMethodName) {
1364            if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
1365                CompletionOnMethodName method = (CompletionOnMethodName) astNode;
1366                    
1367                setSourceRange(method.sourceStart, method.selectorEnd);
1368                    
1369                FieldBinding[] fields = scope.enclosingSourceType().fields();
1370                char[][] excludeNames = new char[fields.length][];
1371                for(int i = 0 ; i < fields.length ; i++){
1372                    excludeNames[i] = fields[i].name;
1373                }
1374                
1375                this.completionToken = method.selector;
1376                
1377                findVariableNames(this.completionToken, method.returnType, excludeNames, null, FIELD, method.modifiers);
1378            }
1379        } else if (astNode instanceof CompletionOnFieldName) {
1380            if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
1381                CompletionOnFieldName field = (CompletionOnFieldName) astNode;
1382                
1383                FieldBinding[] fields = scope.enclosingSourceType().fields();
1384                char[][] excludeNames = new char[fields.length][];
1385                for(int i = 0 ; i < fields.length ; i++){
1386                    excludeNames[i] = fields[i].name;
1387                }
1388                
1389                this.completionToken = field.realName;
1390                
1391                findVariableNames(field.realName, field.type, excludeNames, null, FIELD, field.modifiers);
1392            }
1393        } else if (astNode instanceof CompletionOnLocalName || astNode instanceof CompletionOnArgumentName) {
1394            if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
1395                LocalDeclaration variable = (LocalDeclaration) astNode;
1396                
1397                int kind;
1398                if (variable instanceof CompletionOnLocalName){
1399                    this.completionToken = ((CompletionOnLocalName) variable).realName;
1400                    kind = LOCAL;
1401                } else {
1402                    CompletionOnArgumentName arg = (CompletionOnArgumentName) variable;
1403                    this.completionToken = arg.realName;
1404                    kind = arg.isCatchArgument ? LOCAL : ARGUMENT;
1405                }
1406                
1407                char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, variable);
1408                
1409                char[][] forbiddenNames = findVariableFromUnresolvedReference(variable, (BlockScope)scope, alreadyDefinedName);
1410                
1411                LocalVariableBinding[] locals = ((BlockScope)scope).locals;
1412                char[][] discouragedNames = new char[locals.length][];
1413                int localCount = 0;
1414                for(int i = 0 ; i < locals.length ; i++){
1415                    if (locals[i] != null) {
1416                        discouragedNames[localCount++] = locals[i].name;
1417                    }
1418                }
1419                
1420                System.arraycopy(discouragedNames, 0, discouragedNames = new char[localCount][], 0, localCount);
1421                
1422                findVariableNames(this.completionToken, variable.type, discouragedNames, forbiddenNames, kind, variable.modifiers);
1423            }
1424        } else if (astNode instanceof CompletionOnKeyword) {
1425            if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1426                CompletionOnKeyword keyword = (CompletionOnKeyword)astNode;
1427                findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), keyword.canCompleteEmptyToken(), false);
1428            }
1429        } else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
1430            if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
1431                CompletionOnParameterizedQualifiedTypeReference ref = (CompletionOnParameterizedQualifiedTypeReference) astNode;
1432                
1433                this.insideQualifiedReference = true;
1434
1435                this.assistNodeIsClass = ref.isClass();
1436                this.assistNodeIsException = ref.isException();
1437                this.assistNodeIsInterface = ref.isInterface();
1438                this.assistNodeIsSuperType = ref.isSuperType();
1439                
1440                this.completionToken = ref.completionIdentifier;
1441                long completionPosition = ref.sourcePositions[ref.tokens.length];
1442                setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
1443                
1444                ObjectVector typesFound = new ObjectVector();
1445                if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
1446                    findExceptionFromTryStatement(
1447                            this.completionToken,
1448                            (ReferenceBinding)qualifiedBinding,
1449                            scope.enclosingSourceType(),
1450                            (BlockScope)scope,
1451                            typesFound);
1452                }
1453                
1454                findMemberTypes(
1455                    this.completionToken,
1456                    (ReferenceBinding) qualifiedBinding,
1457                    scope,
1458                    scope.enclosingSourceType(),
1459                    false,
1460                    false,
1461                    typesFound);
1462            }
1463        } else if (astNode instanceof CompletionOnMarkerAnnotationName) {
1464            CompletionOnMarkerAnnotationName annot = (CompletionOnMarkerAnnotationName) astNode;
1465            
1466            CompletionOnAnnotationOfType fakeType = (CompletionOnAnnotationOfType)scope.parent.referenceContext();
1467            if (fakeType.annotations[0] == annot) {
1468                // When the completion is inside a method body the annotation cannot be accuratly attached to the correct node by completion recovery.
1469
// So 'targetedElement' is not computed in this case.
1470
if (scope.parent.parent == null || !(scope.parent.parent instanceof MethodScope)) {
1471                    this.targetedElement = computeTargetedElement(fakeType);
1472                }
1473                
1474            }
1475            
1476            this.assistNodeIsAnnotation = true;
1477            if (annot.type instanceof CompletionOnSingleTypeReference) {
1478                CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) annot.type;
1479                this.completionToken = type.token;
1480                setSourceRange(type.sourceStart, type.sourceEnd);
1481                
1482                findTypesAndPackages(this.completionToken, scope, new ObjectVector());
1483            } else if (annot.type instanceof CompletionOnQualifiedTypeReference) {
1484                this.insideQualifiedReference = true;
1485                
1486                CompletionOnQualifiedTypeReference type = (CompletionOnQualifiedTypeReference) annot.type;
1487                this.completionToken = type.completionIdentifier;
1488                long completionPosition = type.sourcePositions[type.tokens.length];
1489                if (qualifiedBinding instanceof PackageBinding) {
1490
1491                    setSourceRange(astNode.sourceStart, (int) completionPosition);
1492                    // replace to the end of the completion identifier
1493
findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
1494                } else {
1495                    setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
1496
1497                    findMemberTypes(
1498                        this.completionToken,
1499                        (ReferenceBinding) qualifiedBinding,
1500                        scope,
1501                        scope.enclosingSourceType(),
1502                        false,
1503                        false,
1504                        new ObjectVector());
1505                }
1506            }
1507        } else if (astNode instanceof CompletionOnMemberValueName) {
1508            CompletionOnMemberValueName memberValuePair = (CompletionOnMemberValueName) astNode;
1509            Annotation annotation = (Annotation) astNodeParent;
1510            
1511            this.completionToken = memberValuePair.name;
1512            
1513            ReferenceBinding annotationType = (ReferenceBinding)annotation.resolvedType;
1514            
1515            if (annotationType != null && annotationType.isAnnotationType()) {
1516                if (!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
1517                    this.findAnnotationAttributes(this.completionToken, annotation.memberValuePairs(), annotationType);
1518                }
1519                if (this.assistNodeCanBeSingleMemberAnnotation) {
1520                    if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
1521                        findTypesAndPackages(this.completionToken, scope, new ObjectVector());
1522                    } else {
1523                        if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
1524                            char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, FakeInvocationSite);
1525                            
1526                            findUnresolvedReference(
1527                                    memberValuePair.sourceStart,
1528                                    memberValuePair.sourceEnd,
1529                                    (BlockScope)scope,
1530                                    alreadyDefinedName);
1531                        }
1532                        findVariablesAndMethods(
1533                            this.completionToken,
1534                            scope,
1535                            FakeInvocationSite,
1536                            scope,
1537                            insideTypeAnnotation,
1538                            true);
1539                        // can be the start of a qualified type name
1540
findTypesAndPackages(this.completionToken, scope, new ObjectVector());
1541                    }
1542                }
1543            }
1544        } else if(astNode instanceof CompletionOnBrankStatementLabel) {
1545            if (!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) {
1546                CompletionOnBrankStatementLabel label = (CompletionOnBrankStatementLabel) astNode;
1547                
1548                this.completionToken = label.label;
1549                
1550                this.findLabels(this.completionToken, label.possibleLabels);
1551            }
1552        } else if(astNode instanceof CompletionOnMessageSendName) {
1553            if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1554                CompletionOnMessageSendName messageSend = (CompletionOnMessageSendName) astNode;
1555                
1556                this.insideQualifiedReference = true;
1557                this.completionToken = messageSend.selector;
1558                boolean onlyStatic = false;
1559                TypeBinding receiverType = null;
1560                if(qualifiedBinding instanceof VariableBinding) {
1561                    receiverType = ((VariableBinding)qualifiedBinding).type;
1562                } else if(qualifiedBinding instanceof MethodBinding) {
1563                    receiverType = ((MethodBinding)qualifiedBinding).returnType;
1564                } else if(qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
1565                    onlyStatic = true;
1566                    receiverType = (TypeBinding)qualifiedBinding;
1567                }
1568                if(receiverType != null && receiverType instanceof ReferenceBinding) {
1569                    TypeBinding[] typeArgTypes = computeTypesIfCorrect(messageSend.typeArguments);
1570                    if(typeArgTypes != null) {
1571                        this.findMethods(
1572                                this.completionToken,
1573                                typeArgTypes,
1574                                null,
1575                                (ReferenceBinding)receiverType.capture(scope, messageSend.receiver.sourceEnd),
1576                                scope,
1577                                new ObjectVector(),
1578                                onlyStatic,
1579                                false,
1580                                false,
1581                                messageSend,
1582                                scope,
1583                                false,
1584                                false,
1585                                false,
1586                                null,
1587                                null,
1588                                null,
1589                                false);
1590                    }
1591                }
1592            }
1593        // Completion on Javadoc nodes
1594
} else if ((astNode.bits & ASTNode.InsideJavadoc) != 0) {
1595            if (astNode instanceof CompletionOnJavadocSingleTypeReference) {
1596
1597                CompletionOnJavadocSingleTypeReference typeRef = (CompletionOnJavadocSingleTypeReference) astNode;
1598                this.completionToken = typeRef.token;
1599                this.javadocTagPosition = typeRef.tagSourceStart;
1600                setSourceRange(typeRef.sourceStart, typeRef.sourceEnd);
1601                findTypesAndPackages(this.completionToken, scope, new ObjectVector());
1602
1603            } else if (astNode instanceof CompletionOnJavadocQualifiedTypeReference) {
1604
1605                this.insideQualifiedReference = true;
1606
1607                CompletionOnJavadocQualifiedTypeReference typeRef = (CompletionOnJavadocQualifiedTypeReference) astNode;
1608                this.completionToken = typeRef.completionIdentifier;
1609                long completionPosition = typeRef.sourcePositions[typeRef.tokens.length];
1610                this.javadocTagPosition = typeRef.tagSourceStart;
1611
1612                // get the source positions of the completion identifier
1613
if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
1614                    if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
1615                            ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF))) {
1616                        int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32);
1617                        setSourceRange(rangeStart, (int) completionPosition);
1618                        findMemberTypes(this.completionToken,
1619                            (ReferenceBinding) qualifiedBinding,
1620                            scope,
1621                            scope.enclosingSourceType(),
1622                            false,
1623                            false,
1624                            new ObjectVector());
1625                    }
1626                } else if (qualifiedBinding instanceof PackageBinding) {
1627
1628                    setSourceRange(astNode.sourceStart, (int) completionPosition);
1629                    // replace to the end of the completion identifier
1630
findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
1631                }
1632            } else if (astNode instanceof CompletionOnJavadocFieldReference) {
1633
1634                this.insideQualifiedReference = true;
1635                CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) astNode;
1636                this.completionToken = fieldRef.token;
1637                long completionPosition = fieldRef.nameSourcePosition;
1638                this.javadocTagPosition = fieldRef.tagSourceStart;
1639
1640                if (fieldRef.receiverType != null && fieldRef.receiverType.isValidBinding()) {
1641                    ReferenceBinding receiverType = (ReferenceBinding) fieldRef.receiverType;
1642                    int rangeStart = (int) (completionPosition >>> 32);
1643                    if (fieldRef.receiver.isThis()) {
1644                        if (fieldRef.completeInText()) {
1645                            rangeStart = fieldRef.separatorPosition;
1646                        }
1647                    } else if (fieldRef.completeInText()) {
1648                        rangeStart = fieldRef.receiver.sourceStart;
1649                    }
1650                    setSourceRange(rangeStart, (int) completionPosition);
1651
1652                    if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)
1653                            || !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) {
1654                        findFields(this.completionToken,
1655                            receiverType,
1656                            scope,
1657                            new ObjectVector(),
1658                            new ObjectVector(),
1659                            false, /*not only static */
1660                            fieldRef,
1661                            scope,
1662                            false,
1663                            true,
1664                            null,
1665                            null,
1666                            null,
1667                            false);
1668                    }
1669
1670                    if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
1671                            || !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
1672                        findMethods(this.completionToken,
1673                            null,
1674                            null,
1675                            receiverType,
1676                            scope,
1677                            new ObjectVector(),
1678                            false, /*not only static */
1679                            false,
1680                            false,
1681                            fieldRef,
1682                            scope,
1683                            false,
1684                            false,
1685                            true,
1686                            null,
1687                            null,
1688                            null,
1689                            false);
1690                        if (fieldRef.receiverType instanceof ReferenceBinding) {
1691                            ReferenceBinding refBinding = (ReferenceBinding)fieldRef.receiverType;
1692                            if (this.completionToken == null
1693                                    || CharOperation.prefixEquals(this.completionToken, refBinding.sourceName)
1694                                    || (this.options.camelCaseMatch && CharOperation.camelCaseMatch(this.completionToken, refBinding.sourceName))) {
1695                                findConstructors(refBinding, null, scope, fieldRef, false);
1696                            }
1697                        }
1698                    }
1699                }
1700            } else if (astNode instanceof CompletionOnJavadocMessageSend) {
1701
1702                CompletionOnJavadocMessageSend messageSend = (CompletionOnJavadocMessageSend) astNode;
1703                TypeBinding[] argTypes = null; //computeTypes(messageSend.arguments);
1704
this.completionToken = messageSend.selector;
1705                this.javadocTagPosition = messageSend.tagSourceStart;
1706
1707                // Set source range
1708
int rangeStart = astNode.sourceStart;
1709                if (messageSend.receiver.isThis()) {
1710                    if (messageSend.completeInText()) {
1711                        rangeStart = messageSend.separatorPosition;
1712                    }
1713                } else if (messageSend.completeInText()) {
1714                    rangeStart = messageSend.receiver.sourceStart;
1715                }
1716                setSourceRange(rangeStart, astNode.sourceEnd, false);
1717
1718                if (qualifiedBinding == null) {
1719                    if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1720                        findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope);
1721                    }
1722                } else if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1723                    findMethods(
1724                        this.completionToken,
1725                        null,
1726                        argTypes,
1727                        (ReferenceBinding) ((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
1728                        scope,
1729                        new ObjectVector(),
1730                        false,
1731                        false/* prefix match */,
1732                        false,
1733                        messageSend,
1734                        scope,
1735                        false,
1736                        messageSend.receiver instanceof SuperReference,
1737                        true,
1738                        null,
1739                        null,
1740                        null,
1741                        false);
1742                }
1743            } else if (astNode instanceof CompletionOnJavadocAllocationExpression) {
1744// setSourceRange(astNode.sourceStart, astNode.sourceEnd, false);
1745

1746                CompletionOnJavadocAllocationExpression allocExpression = (CompletionOnJavadocAllocationExpression) astNode;
1747                this.javadocTagPosition = allocExpression.tagSourceStart;
1748                int rangeStart = astNode.sourceStart;
1749                if (allocExpression.type.isThis()) {
1750                    if (allocExpression.completeInText()) {
1751                        rangeStart = allocExpression.separatorPosition;
1752                    }
1753                } else if (allocExpression.completeInText()) {
1754                    rangeStart = allocExpression.type.sourceStart;
1755                }
1756                setSourceRange(rangeStart, astNode.sourceEnd, false);
1757                TypeBinding[] argTypes = computeTypes(allocExpression.arguments);
1758
1759                ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
1760                if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && ref.isClass()) {
1761                    findConstructors(ref, argTypes, scope, allocExpression, false);
1762                }
1763            } else if (astNode instanceof CompletionOnJavadocParamNameReference) {
1764                if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
1765                    CompletionOnJavadocParamNameReference paramRef = (CompletionOnJavadocParamNameReference) astNode;
1766                    setSourceRange(paramRef.tagSourceStart, paramRef.tagSourceEnd);
1767                    findJavadocParamNames(paramRef.token, paramRef.missingParams, false);
1768                    findJavadocParamNames(paramRef.token, paramRef.missingTypeParams, true);
1769                }
1770            } else if (astNode instanceof CompletionOnJavadocTypeParamReference) {
1771                if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
1772                    CompletionOnJavadocTypeParamReference paramRef = (CompletionOnJavadocTypeParamReference) astNode;
1773                    setSourceRange(paramRef.tagSourceStart, paramRef.tagSourceEnd);
1774                    findJavadocParamNames(paramRef.token, paramRef.missingParams, true);
1775                }
1776            } else if (astNode instanceof CompletionOnJavadocTag) {
1777                CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode;
1778                setSourceRange(javadocTag.tagSourceStart, javadocTag.sourceEnd);
1779                findJavadocBlockTags(javadocTag);
1780                findJavadocInlineTags(javadocTag);
1781            }
1782        }
1783        return true;
1784    }
1785
1786    public void complete(IType type, char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
1787        if(this.requestor != null){
1788            this.requestor.beginReporting();
1789        }
1790        boolean contextAccepted = false;
1791        IType topLevelType = type;
1792        while(topLevelType.getDeclaringType() != null) {
1793            topLevelType = topLevelType.getDeclaringType();
1794        }
1795        
1796        this.fileName = topLevelType.getParent().getElementName().toCharArray();
1797        CompilationResult compilationResult = new CompilationResult(this.fileName, 1, 1, this.compilerOptions.maxProblemsPerUnit);
1798    
1799        CompilationUnitDeclaration compilationUnit = null;
1800    
1801        try {
1802            // TypeConverter is used instead of SourceTypeConverter because the type
1803
// to convert can be a binary type or a source type
1804
TypeDeclaration typeDeclaration = null;
1805            if (type instanceof SourceType) {
1806                SourceType sourceType = (SourceType) type;
1807                ISourceType info = (ISourceType) sourceType.getElementInfo();
1808                compilationUnit = SourceTypeConverter.buildCompilationUnit(
1809                    new ISourceType[] {info},//sourceTypes[0] is always toplevel here
1810
SourceTypeConverter.FIELD_AND_METHOD // need field and methods
1811
| SourceTypeConverter.MEMBER_TYPE, // need member types
1812
// no need for field initialization
1813
this.problemReporter,
1814                    compilationResult);
1815                if (compilationUnit.types != null)
1816                    typeDeclaration = compilationUnit.types[0];
1817            } else {
1818                compilationUnit = new CompilationUnitDeclaration(this.problemReporter, compilationResult, 0);
1819                typeDeclaration = BinaryTypeConverter.buildTypeDeclaration(type, compilationUnit, compilationResult);
1820            }
1821        
1822            if(typeDeclaration != null) {
1823                // build AST from snippet
1824
Initializer fakeInitializer = parseSnippeInitializer(snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic);
1825                
1826                // merge AST
1827
FieldDeclaration[] oldFields = typeDeclaration.fields;
1828                FieldDeclaration[] newFields = null;
1829                if (oldFields != null) {
1830                    newFields = new FieldDeclaration[oldFields.length + 1];
1831                    System.arraycopy(oldFields, 0, newFields, 0, oldFields.length);
1832                    newFields[oldFields.length] = fakeInitializer;
1833                } else {
1834                    newFields = new FieldDeclaration[] {fakeInitializer};
1835                }
1836                typeDeclaration.fields = newFields;
1837        
1838                if(DEBUG) {
1839                    System.out.println("SNIPPET COMPLETION AST :"); //$NON-NLS-1$
1840
System.out.println(compilationUnit.toString());
1841                }
1842                
1843                if (compilationUnit.types != null) {
1844                    try {
1845                        this.lookupEnvironment.buildTypeBindings(compilationUnit, null /*no access restriction*/);
1846                
1847                        if ((this.unitScope = compilationUnit.scope) != null) {
1848                            this.lookupEnvironment.completeTypeBindings(compilationUnit, true);
1849                            compilationUnit.scope.faultInTypes();
1850                            compilationUnit.resolve();
1851                        }
1852                    } catch (CompletionNodeFound e) {
1853                        // completionNodeFound = true;
1854
if (e.astNode != null) {
1855                            // if null then we found a problem in the completion node
1856
contextAccepted = complete(e.astNode, this.parser.assistNodeParent, e.qualifiedBinding, e.scope, e.insideTypeAnnotation);
1857                        }
1858                    }
1859                }
1860                if(this.noProposal && this.problem != null) {
1861                    if(!contextAccepted) {
1862                        contextAccepted = true;
1863                        this.requestor.acceptContext(new CompletionContext());
1864                    }
1865                    this.requestor.completionFailure(this.problem);
1866                    if(DEBUG) {
1867                        this.printDebug(this.problem);
1868                    }
1869                }
1870            }
1871        } catch (IndexOutOfBoundsException JavaDoc e) { // work-around internal failure - 1GEMF6D (added with fix of 99629)
1872
if(DEBUG) {
1873                System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1874
e.printStackTrace(System.out);
1875            }
1876        } catch (InvalidCursorLocation e) { // may eventually report a usefull error (added to fix 99629)
1877
if(DEBUG) {
1878                System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1879
e.printStackTrace(System.out);
1880            }
1881        } catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object (added with fix of 99629)
1882
if(DEBUG) {
1883                System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1884
e.printStackTrace(System.out);
1885            }
1886        } catch (CompletionNodeFound e){ // internal failure - bugs 5618 (added with fix of 99629)
1887
if(DEBUG) {
1888                System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1889
e.printStackTrace(System.out);
1890            }
1891        } catch(JavaModelException e) {
1892            // Do nothing
1893
}
1894        if(!contextAccepted) {
1895            contextAccepted = true;
1896            this.requestor.acceptContext(new CompletionContext());
1897        }
1898        if(this.requestor != null){
1899            this.requestor.endReporting();
1900        }
1901    }
1902    
1903    private Initializer parseSnippeInitializer(char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
1904        StringBuffer JavaDoc prefix = new StringBuffer JavaDoc();
1905        prefix.append("public class FakeType {\n "); //$NON-NLS-1$
1906
if(isStatic) {
1907            prefix.append("static "); //$NON-NLS-1$
1908
}
1909        prefix.append("{\n"); //$NON-NLS-1$
1910
for (int i = 0; i < localVariableTypeNames.length; i++) {
1911            ASTNode.printModifiers(localVariableModifiers[i], prefix);
1912            prefix.append(' ');
1913            prefix.append(localVariableTypeNames[i]);
1914            prefix.append(' ');
1915            prefix.append(localVariableNames[i]);
1916            prefix.append(';');
1917        }
1918        
1919        char[] fakeSource = CharOperation.concat(prefix.toString().toCharArray(), snippet, "}}".toCharArray());//$NON-NLS-1$
1920
this.offset = prefix.length();
1921        
1922        String JavaDoc encoding = this.compilerOptions.defaultEncoding;
1923        BasicCompilationUnit fakeUnit = new BasicCompilationUnit(
1924            fakeSource,
1925            null,
1926            "FakeType.java", //$NON-NLS-1$
1927
encoding);
1928            
1929        this.actualCompletionPosition = prefix.length() + position - 1;
1930            
1931        CompilationResult fakeResult = new CompilationResult(fakeUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
1932        CompilationUnitDeclaration fakeAST = this.parser.dietParse(fakeUnit, fakeResult, this.actualCompletionPosition);
1933        
1934        parseBlockStatements(fakeAST, this.actualCompletionPosition);
1935        
1936        return (Initializer)fakeAST.types[0].fields[0];
1937    }
1938
1939    /**
1940     * Ask the engine to compute a completion at the specified position
1941     * of the given compilation unit.
1942     *
1943     * No return
1944     * completion results are answered through a requestor.
1945     *
1946     * @param sourceUnit org.eclipse.jdt.internal.compiler.env.ICompilationUnit
1947     * the source of the current compilation unit.
1948     *
1949     * @param completionPosition int
1950     * a position in the source where the completion is taking place.
1951     * This position is relative to the source provided.
1952     */

1953    public void complete(ICompilationUnit sourceUnit, int completionPosition, int pos) {
1954
1955        if(DEBUG) {
1956            System.out.print("COMPLETION IN "); //$NON-NLS-1$
1957
System.out.print(sourceUnit.getFileName());
1958            System.out.print(" AT POSITION "); //$NON-NLS-1$
1959
System.out.println(completionPosition);
1960            System.out.println("COMPLETION - Source :"); //$NON-NLS-1$
1961
System.out.println(sourceUnit.getContents());
1962        }
1963        this.requestor.beginReporting();
1964        boolean contextAccepted = false;
1965        try {
1966            this.fileName = sourceUnit.getFileName();
1967            this.actualCompletionPosition = completionPosition - 1;
1968            this.offset = pos;
1969            // for now until we can change the UI.
1970
CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
1971            CompilationUnitDeclaration parsedUnit = this.parser.dietParse(sourceUnit, result, this.actualCompletionPosition);
1972
1973            // boolean completionNodeFound = false;
1974
if (parsedUnit != null) {
1975                if(DEBUG) {
1976                    System.out.println("COMPLETION - Diet AST :"); //$NON-NLS-1$
1977
System.out.println(parsedUnit.toString());
1978                }
1979
1980                // scan the package & import statements first
1981
if (parsedUnit.currentPackage instanceof CompletionOnPackageReference) {
1982                    contextAccepted = true;
1983                    this.buildContext(parsedUnit.currentPackage, null, null, null);
1984                    if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
1985                        findPackages((CompletionOnPackageReference) parsedUnit.currentPackage);
1986                    }
1987                    if(this.noProposal && this.problem != null) {
1988                        this.requestor.completionFailure(this.problem);
1989                        if(DEBUG) {
1990                            this.printDebug(this.problem);
1991                        }
1992                    }
1993                    return;
1994                }
1995
1996                ImportReference[] imports = parsedUnit.imports;
1997                if (imports != null) {
1998                    for (int i = 0, length = imports.length; i < length; i++) {
1999                        ImportReference importReference = imports[i];
2000                        if (importReference instanceof CompletionOnImportReference) {
2001                            this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
2002                            if ((this.unitScope = parsedUnit.scope) != null) {
2003                                contextAccepted = true;
2004                                this.buildContext(importReference, null, null, null);
2005                                
2006                                setSourceRange(
2007                                    importReference.sourceStart,
2008                                    importReference.declarationSourceEnd);
2009                                
2010                                char[][] oldTokens = importReference.tokens;
2011                                int tokenCount = oldTokens.length;
2012                                if (tokenCount == 1) {
2013                                    findImports((CompletionOnImportReference)importReference, true);
2014                                } else if(tokenCount > 1){
2015                                    this.insideQualifiedReference = true;
2016                                    
2017                                    char[] lastToken = oldTokens[tokenCount - 1];
2018                                    char[][] qualifierTokens = CharOperation.subarray(oldTokens, 0, tokenCount - 1);
2019                                    
2020                                    Binding binding = this.unitScope.getTypeOrPackage(qualifierTokens);
2021                                    if(binding != null) {
2022                                        if(binding instanceof PackageBinding) {
2023                                            findImports((CompletionOnImportReference)importReference, false);
2024                                        } else {
2025                                            ReferenceBinding ref = (ReferenceBinding) binding;
2026                                            if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
2027                                                this.findImportsOfMemberTypes(lastToken, ref, importReference.isStatic());
2028                                            }
2029                                            if(importReference.isStatic()) {
2030                                                if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
2031                                                    long positions = importReference.sourcePositions[importReference.sourcePositions.length - 1];
2032                                                    setSourceRange((int) (positions >>> 32), (int) positions);
2033                                                    this.findImportsOfStaticFields(lastToken, ref);
2034                                                    setSourceRange(importReference.sourceStart, importReference.declarationSourceEnd);
2035                                                }
2036                                                if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
2037                                                    this.findImportsOfStaticMethods(lastToken, ref);
2038                                                }
2039                                            }
2040                                        }
2041                                    }
2042                                }
2043                                
2044                                if(this.noProposal && this.problem != null) {
2045                                    this.requestor.completionFailure(this.problem);
2046                                    if(DEBUG) {
2047                                        this.printDebug(this.problem);
2048                                    }
2049                                }
2050                            }
2051                            return;
2052                        } else if(importReference instanceof CompletionOnKeyword) {
2053                            contextAccepted = true;
2054                            this.buildContext(importReference, null, null, null);
2055                            if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
2056                                setSourceRange(importReference.sourceStart, importReference.sourceEnd);
2057                                CompletionOnKeyword keyword = (CompletionOnKeyword)importReference;
2058                                findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), false, false);
2059                            }
2060                            if(this.noProposal && this.problem != null) {
2061                                this.requestor.completionFailure(this.problem);
2062                                if(DEBUG) {
2063                                    this.printDebug(this.problem);
2064                                }
2065                            }
2066                            return;
2067                        }
2068                    }
2069                }
2070
2071                if (parsedUnit.types != null) {
2072                    try {
2073                        this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
2074
2075                        if ((this.unitScope = parsedUnit.scope) != null) {
2076                            this.source = sourceUnit.getContents();
2077                            this.lookupEnvironment.completeTypeBindings(parsedUnit, true);
2078                            parsedUnit.scope.faultInTypes();
2079                            parseBlockStatements(parsedUnit, this.actualCompletionPosition);
2080                            if(DEBUG) {
2081                                System.out.println("COMPLETION - AST :"); //$NON-NLS-1$
2082
System.out.println(parsedUnit.toString());
2083                            }
2084                            parsedUnit.resolve();
2085                        }
2086                    } catch (CompletionNodeFound e) {
2087                        // completionNodeFound = true;
2088
if (e.astNode != null) {
2089                            if(DEBUG) {
2090                                System.out.print("COMPLETION - Completion node : "); //$NON-NLS-1$
2091
System.out.println(e.astNode.toString());
2092                                if(this.parser.assistNodeParent != null) {
2093                                    System.out.print("COMPLETION - Parent Node : "); //$NON-NLS-1$
2094
System.out.println(this.parser.assistNodeParent);
2095                                }
2096                            }
2097                            // if null then we found a problem in the completion node
2098
contextAccepted = complete(e.astNode, this.parser.assistNodeParent, e.qualifiedBinding, e.scope, e.insideTypeAnnotation);
2099                        }
2100                    }
2101                }
2102            }
2103            
2104            if(this.noProposal && this.problem != null) {
2105                if(!contextAccepted) {
2106                    contextAccepted = true;
2107                    CompletionContext context = new CompletionContext();
2108                    context.setOffset(completionPosition - this.offset);
2109                    context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
2110                    this.requestor.acceptContext(context);
2111                }
2112                this.requestor.completionFailure(this.problem);
2113                if(DEBUG) {
2114                    this.printDebug(this.problem);
2115                }
2116            }
2117            /* Ignore package, import, class & interface keywords for now...
2118                    if (!completionNodeFound) {
2119                        if (parsedUnit == null || parsedUnit.types == null) {
2120                            // this is not good enough... can still be trying to define a second type
2121                            CompletionScanner scanner = (CompletionScanner) this.parser.scanner;
2122                            setSourceRange(scanner.completedIdentifierStart, scanner.completedIdentifierEnd);
2123                            findKeywords(scanner.completionIdentifier, mainDeclarations, null);
2124                        }
2125                        // currently have no way to know if extends/implements are possible keywords
2126                    }
2127            */

2128        } catch (IndexOutOfBoundsException JavaDoc e) { // work-around internal failure - 1GEMF6D
2129
if(DEBUG) {
2130                System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
2131
e.printStackTrace(System.out);
2132            }
2133        } catch (InvalidCursorLocation e) { // may eventually report a usefull error
2134
if(DEBUG) {
2135                System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
2136
e.printStackTrace(System.out);
2137            }
2138        } catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object
2139
if(DEBUG) {
2140                System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
2141
e.printStackTrace(System.out);
2142            }
2143        } catch (CompletionNodeFound e){ // internal failure - bugs 5618
2144
if(DEBUG) {
2145                System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
2146
e.printStackTrace(System.out);
2147            }
2148        } finally {
2149            reset();
2150            if(!contextAccepted) {
2151                contextAccepted = true;
2152                CompletionContext context = new CompletionContext();
2153                context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
2154                context.setOffset(completionPosition - this.offset);
2155                this.requestor.acceptContext(context);
2156            }
2157            this.requestor.endReporting();
2158        }
2159    }
2160
2161    private long computeTargetedElement(CompletionOnAnnotationOfType fakeNode) {
2162        ASTNode annotatedElement = fakeNode.potentialAnnotatedNode;
2163        
2164        if (annotatedElement instanceof TypeDeclaration) {
2165            TypeDeclaration annotatedTypeDeclaration = (TypeDeclaration) annotatedElement;
2166            if (TypeDeclaration.kind(annotatedTypeDeclaration.modifiers) == TypeDeclaration.ANNOTATION_TYPE_DECL) {
2167                return TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType;
2168            }
2169            return TagBits.AnnotationForType;
2170        } else if (annotatedElement instanceof FieldDeclaration) {
2171            if (fakeNode.isParameter) {
2172                return TagBits.AnnotationForParameter;
2173            }
2174            return TagBits.AnnotationForField;
2175        } else if (annotatedElement instanceof MethodDeclaration) {
2176            return TagBits.AnnotationForMethod;
2177        } else if (annotatedElement instanceof Argument) {
2178            return TagBits.AnnotationForParameter;
2179        } else if (annotatedElement instanceof ConstructorDeclaration) {
2180            return TagBits.AnnotationForConstructor;
2181        } else if (annotatedElement instanceof LocalDeclaration) {
2182            return TagBits.AnnotationForLocalVariable;
2183        } else if (annotatedElement instanceof ImportReference) {
2184            return TagBits.AnnotationForPackage;
2185        }
2186        return 0;
2187    }
2188    
2189    private TypeBinding[] computeTypes(Expression[] arguments) {
2190        if (arguments == null) return null;
2191        int argsLength = arguments.length;
2192        TypeBinding[] argTypes = new TypeBinding[argsLength];
2193        for (int a = argsLength; --a >= 0;) {
2194            argTypes[a] = arguments[a].resolvedType;
2195        }
2196        return argTypes;
2197    }
2198    
2199    private TypeBinding[] computeTypesIfCorrect(Expression[] arguments) {
2200        if (arguments == null) return null;
2201        int argsLength = arguments.length;
2202        TypeBinding[] argTypes = new TypeBinding[argsLength];
2203        for (int a = argsLength; --a >= 0;) {
2204            TypeBinding typeBinding = arguments[a].resolvedType;
2205            if(typeBinding == null || !typeBinding.isValidBinding()) return null;
2206            argTypes[a] = typeBinding;
2207        }
2208        return argTypes;
2209    }
2210    
2211    private void findAnnotationAttributes(char[] token, MemberValuePair[] attributesFound, ReferenceBinding annotation) {
2212        MethodBinding[] methods = annotation.availableMethods();
2213        nextAttribute: for (int i = 0; i < methods.length; i++) {
2214            MethodBinding method = methods[i];
2215            
2216            if(!CharOperation.prefixEquals(token, method.selector, false)
2217                    && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, method.selector))) continue nextAttribute;
2218            
2219            int length = attributesFound == null ? 0 : attributesFound.length;
2220            for (int j = 0; j < length; j++) {
2221                if(CharOperation.equals(method.selector, attributesFound[j].name, false)) continue nextAttribute;
2222            }
2223            
2224            int relevance = computeBaseRelevance();
2225            relevance += computeRelevanceForResolution();
2226            relevance += computeRelevanceForInterestingProposal(method);
2227            relevance += computeRelevanceForCaseMatching(token, method.selector);
2228            relevance += computeRelevanceForQualification(false);
2229            relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
2230            
2231            this.noProposal = false;
2232            if(!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
2233                CompletionProposal proposal = this.createProposal(CompletionProposal.ANNOTATION_ATTRIBUTE_REF, this.actualCompletionPosition);
2234                proposal.setDeclarationSignature(getSignature(method.declaringClass));
2235                proposal.setSignature(getSignature(method.returnType));
2236                proposal.setName(method.selector);
2237                proposal.setCompletion(method.selector);
2238                proposal.setFlags(method.modifiers);
2239                proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
2240                proposal.setRelevance(relevance);
2241                this.requestor.accept(proposal);
2242                if(DEBUG) {
2243                    this.printDebug(proposal);
2244                }
2245            }
2246        }
2247    }
2248    private void findAnonymousType(
2249        ReferenceBinding currentType,
2250        TypeBinding[] argTypes,
2251        Scope scope,
2252        InvocationSite invocationSite) {
2253
2254        if (currentType.isInterface()) {
2255            char[] completion = CharOperation.NO_CHAR;
2256            int relevance = computeBaseRelevance();
2257            relevance += computeRelevanceForResolution();
2258            relevance += computeRelevanceForInterestingProposal();
2259            relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
2260            
2261            this.noProposal = false;
2262            if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
2263                CompletionProposal proposal = this.createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
2264                proposal.setDeclarationSignature(getSignature(currentType));
2265                proposal.setDeclarationKey(currentType.computeUniqueKey());
2266                proposal.setSignature(
2267                        createMethodSignature(
2268                                CharOperation.NO_CHAR_CHAR,
2269                                CharOperation.NO_CHAR_CHAR,
2270                                CharOperation.NO_CHAR,
2271                                CharOperation.NO_CHAR));
2272                //proposal.setOriginalSignature(null);
2273
//proposal.setUniqueKey(null);
2274
proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
2275                proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
2276                //proposal.setParameterPackageNames(null);
2277
//proposal.setParameterTypeNames(null);
2278
//proposal.setPackageName(null);
2279
//proposal.setTypeName(null);
2280
proposal.setCompletion(completion);
2281                proposal.setFlags(Flags.AccPublic);
2282                proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
2283                proposal.setRelevance(relevance);
2284                this.requestor.accept(proposal);
2285                if(DEBUG) {
2286                    this.printDebug(proposal);
2287                }
2288            }
2289        } else {
2290            findConstructors(
2291                currentType,
2292                argTypes,
2293                scope,
2294                invocationSite,
2295                true);
2296        }
2297    }
2298
2299    private void findClassField(char[] token, TypeBinding receiverType, Scope scope) {
2300
2301        if (token == null) return;
2302
2303        if (token.length <= classField.length
2304            && CharOperation.prefixEquals(token, classField, false /* ignore case */
2305        )) {
2306            int relevance = computeBaseRelevance();
2307            relevance += computeRelevanceForResolution();
2308            relevance += computeRelevanceForInterestingProposal();
2309            relevance += computeRelevanceForCaseMatching(token, classField);
2310            relevance += computeRelevanceForExpectingType(scope.getJavaLangClass());
2311            relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); //no access restriction for class field
2312
relevance += R_NON_INHERITED;
2313            
2314            this.noProposal = false;
2315            if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
2316                CompletionProposal proposal = this.createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
2317                //proposal.setDeclarationSignature(null);
2318
char[] signature =
2319                    createNonGenericTypeSignature(
2320                        CharOperation.concatWith(JAVA_LANG, '.'),
2321                        CLASS);
2322                if (this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4) {
2323                    // add type argument
2324
char[] typeArgument = getTypeSignature(receiverType);
2325                    int oldLength = signature.length;
2326                    int argumentLength = typeArgument.length;
2327                    int newLength = oldLength + argumentLength + 2;
2328                    System.arraycopy(signature, 0, signature = new char[newLength], 0, oldLength - 1);
2329                    signature[oldLength - 1] = '<';
2330                    System.arraycopy(typeArgument, 0, signature, oldLength , argumentLength);
2331                    signature[newLength - 2] = '>';
2332                    signature[newLength - 1] = ';';
2333                }
2334                proposal.setSignature(signature);
2335                //proposal.setDeclarationPackageName(null);
2336
//proposal.setDeclarationTypeName(null);
2337
proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
2338                proposal.setTypeName(CLASS);
2339                proposal.setName(classField);
2340                proposal.setCompletion(classField);
2341                proposal.setFlags(Flags.AccStatic | Flags.AccPublic);
2342                proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
2343                proposal.setRelevance(relevance);
2344                this.requestor.accept(proposal);
2345                if(DEBUG) {
2346                    this.printDebug(proposal);
2347                }
2348            }
2349        }
2350    }
2351    private void findEnumConstant(char[] enumConstantName, SwitchStatement switchStatement) {
2352        TypeBinding expressionType = switchStatement.expression.resolvedType;
2353        if(expressionType != null && expressionType.isEnum()) {
2354            ReferenceBinding enumType = (ReferenceBinding) expressionType;
2355            
2356            CaseStatement[] cases = switchStatement.cases;
2357            
2358            char[][] alreadyUsedConstants = new char[switchStatement.caseCount][];
2359            int alreadyUsedConstantCount = 0;
2360            for (int i = 0; i < switchStatement.caseCount; i++) {
2361                Expression caseExpression = cases[i].constantExpression;
2362                if((caseExpression instanceof SingleNameReference)
2363                        && (caseExpression.resolvedType != null && caseExpression.resolvedType.isEnum())) {
2364                    alreadyUsedConstants[alreadyUsedConstantCount++] = ((SingleNameReference)cases[i].constantExpression).token;
2365                }
2366            }
2367            
2368            FieldBinding[] fields = enumType.fields();
2369            
2370            int enumConstantLength = enumConstantName.length;
2371            next : for (int f = fields.length; --f >= 0;) {
2372                FieldBinding field = fields[f];
2373
2374                if (field.isSynthetic()) continue next;
2375
2376                if ((field.modifiers & Flags.AccEnum) == 0) continue next;
2377
2378                if (enumConstantLength > field.name.length) continue next;
2379
2380                if (!CharOperation.prefixEquals(enumConstantName, field.name, false /* ignore case */)
2381                        && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(enumConstantName, field.name))) continue next;
2382                
2383                char[] completion = field.name;
2384                
2385                for (int i = 0; i < alreadyUsedConstantCount; i++) {
2386                    if(CharOperation.equals(alreadyUsedConstants[i], completion)) continue next;
2387                }
2388
2389                int relevance = computeBaseRelevance();
2390                relevance += computeRelevanceForInterestingProposal(field);
2391                relevance += computeRelevanceForEnum();
2392                relevance += computeRelevanceForCaseMatching(enumConstantName, field.name);
2393                relevance += computeRelevanceForExpectingType(field.type);
2394                relevance += computeRelevanceForQualification(false);
2395                relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
2396                
2397                this.noProposal = false;
2398                if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
2399                    CompletionProposal proposal = this.createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
2400                    proposal.setDeclarationSignature(getSignature(field.declaringClass));
2401                    proposal.setSignature(getSignature(field.type));
2402                    proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
2403                    proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
2404                    proposal.setPackageName(field.type.qualifiedPackageName());
2405                    proposal.setTypeName(field.type.qualifiedSourceName());
2406                    proposal.setName(field.name);
2407                    proposal.setCompletion(completion);
2408                    proposal.setFlags(field.modifiers);
2409                    proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
2410                    proposal.setRelevance(relevance);
2411                    this.requestor.accept(proposal);
2412                    if(DEBUG) {
2413                        this.printDebug(proposal);
2414                    }
2415                }
2416            }
2417        }
2418    }
2419    
2420    private void findExceptionFromTryStatement(
2421            char[] typeName,
2422            ReferenceBinding exceptionType,
2423            ReferenceBinding receiverType,
2424            SourceTypeBinding invocationType,
2425            BlockScope scope,
2426            ObjectVector typesFound,
2427            boolean searchSuperClasses) {
2428        
2429        if (searchSuperClasses) {
2430            ReferenceBinding javaLangThrowable = scope.getJavaLangThrowable();
2431            if (exceptionType != javaLangThrowable) {
2432                ReferenceBinding superClass = exceptionType.superclass();
2433                while(superClass != null && superClass != javaLangThrowable) {
2434                    findExceptionFromTryStatement(typeName, superClass, receiverType, invocationType, scope, typesFound, false);
2435                    superClass = superClass.superclass();
2436                }
2437            }
2438        }
2439        
2440        if (typeName.length > exceptionType.sourceName.length)
2441            return;
2442
2443        if (!CharOperation.prefixEquals(typeName, exceptionType.sourceName, false/* ignore case */)
2444                && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, exceptionType.sourceName)))
2445            return;
2446
2447        if (this.options.checkDeprecation &&
2448                exceptionType.isViewedAsDeprecated() &&
2449                !scope.isDefinedInSameUnit(exceptionType))
2450            return;
2451        
2452        if (this.options.checkVisibility) {
2453            if (invocationType != null) {
2454                if (receiverType != null) {
2455                    if (!exceptionType.canBeSeenBy(receiverType, invocationType)) return;
2456                } else {
2457                    if (!exceptionType.canBeSeenBy(exceptionType, invocationType)) return;
2458                }
2459            } else if(!exceptionType.canBeSeenBy(this.unitScope.fPackage)) {
2460                return;
2461            }
2462        }
2463
2464        for (int j = typesFound.size; --j >= 0;) {
2465            ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
2466
2467            if (exceptionType == otherType)
2468                return;
2469
2470            if (CharOperation.equals(exceptionType.sourceName, otherType.sourceName, true)) {
2471
2472                if (exceptionType.enclosingType().isSuperclassOf(otherType.enclosingType()))
2473                    return;
2474
2475                if (otherType.enclosingType().isInterface())
2476                    if (exceptionType.enclosingType()
2477                        .implementsInterface(otherType.enclosingType(), true))
2478                        return;
2479
2480                if (exceptionType.enclosingType().isInterface())
2481                    if (otherType.enclosingType()
2482                        .implementsInterface(exceptionType.enclosingType(), true))
2483                        return;
2484            }
2485        }
2486
2487        typesFound.add(exceptionType);
2488        
2489        char[] completionName = exceptionType.sourceName();
2490        
2491        boolean isQualified = false;
2492        
2493        if(!this.insideQualifiedReference) {
2494            isQualified = true;
2495            
2496            char[] memberPackageName = exceptionType.qualifiedPackageName();
2497            char[] memberTypeName = exceptionType.sourceName();
2498            char[] memberEnclosingTypeNames = null;
2499            
2500            ReferenceBinding enclosingType = exceptionType.enclosingType();
2501            if (enclosingType != null) {
2502                memberEnclosingTypeNames = exceptionType.enclosingType().qualifiedSourceName();
2503            }
2504            
2505            Scope currentScope = scope;
2506            done : while (currentScope != null) { // done when a COMPILATION_UNIT_SCOPE is found
2507

2508                switch (currentScope.kind) {
2509
2510                    case Scope.METHOD_SCOPE :
2511                    case Scope.BLOCK_SCOPE :
2512                        BlockScope blockScope = (BlockScope) currentScope;
2513
2514                        for (int j = 0, length = blockScope.subscopeCount; j < length; j++) {
2515
2516                            if (blockScope.subscopes[j] instanceof ClassScope) {
2517                                SourceTypeBinding localType =
2518                                    ((ClassScope) blockScope.subscopes[j]).referenceContext.binding;
2519                                
2520                                if (localType == exceptionType) {
2521                                    isQualified = false;
2522                                    break done;
2523                                }
2524                            }
2525                        }
2526                        break;
2527
2528                    case Scope.CLASS_SCOPE :
2529                        SourceTypeBinding type = ((ClassScope)currentScope).referenceContext.binding;
2530                        ReferenceBinding[] memberTypes = type.memberTypes();
2531                        if (memberTypes != null) {
2532                            for (int j = 0; j < memberTypes.length; j++) {
2533                                if (memberTypes[j] == exceptionType) {
2534                                    isQualified = false;
2535                                    break done;
2536                                }
2537                            }
2538                        }
2539                        
2540                        
2541                        break;
2542
2543                    case Scope.COMPILATION_UNIT_SCOPE :
2544                        SourceTypeBinding[] types = ((CompilationUnitScope)currentScope).topLevelTypes;
2545                        if (types != null) {
2546                            for (int j = 0; j < types.length; j++) {
2547                                if (types[j] == exceptionType) {
2548                                    isQualified = false;
2549                                    break done;
2550                                }
2551                            }
2552                        }
2553                        break done;
2554                }
2555                currentScope = currentScope.parent;
2556            }
2557            
2558            if (isQualified && mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, exceptionType.modifiers)) {
2559                if (memberPackageName == null || memberPackageName.length == 0)
2560                    if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
2561                        return; // ignore types from the default package from outside it
2562
} else {
2563                isQualified = false;
2564            }
2565            
2566            if (isQualified) {
2567                completionName =
2568                    CharOperation.concat(
2569                            memberPackageName,
2570                            CharOperation.concat(
2571                                    memberEnclosingTypeNames,
2572                                    memberTypeName,
2573                                    '.'),
2574                            '.');
2575            }
2576        }
2577        
2578        int relevance = computeBaseRelevance();
2579        relevance += computeRelevanceForResolution();
2580        relevance += computeRelevanceForInterestingProposal();
2581        relevance += computeRelevanceForCaseMatching(typeName, exceptionType.sourceName);
2582        relevance += computeRelevanceForExpectingType(exceptionType);
2583        relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
2584        if(!insideQualifiedReference) {
2585            relevance += computeRelevanceForQualification(isQualified);
2586        }
2587        relevance += computeRelevanceForClass();
2588        relevance += computeRelevanceForException();
2589            
2590        this.noProposal = false;
2591        if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
2592            createTypeProposal(exceptionType, exceptionType.qualifiedSourceName(), IAccessRule.K_ACCESSIBLE, completionName, relevance);
2593        }
2594    }
2595    
2596    private void findExceptionFromTryStatement(
2597            char[] typeName,
2598            ReferenceBinding receiverType,
2599            SourceTypeBinding invocationType,
2600            BlockScope scope,
2601            ObjectVector typesFound) {
2602        
2603        for (int i = 0; i <= this.expectedTypesPtr; i++) {
2604            ReferenceBinding exceptionType = (ReferenceBinding)this.expectedTypes[i];
2605            
2606            findExceptionFromTryStatement(typeName, exceptionType, receiverType, invocationType, scope, typesFound, true);
2607        }
2608    }
2609    private void findExplicitConstructors(
2610        char[] name,
2611        ReferenceBinding currentType,
2612        MethodScope scope,
2613        InvocationSite invocationSite) {
2614            
2615        ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration)scope.referenceContext;
2616        MethodBinding enclosingConstructor = constructorDeclaration.binding;
2617
2618        // No visibility checks can be performed without the scope & invocationSite
2619
MethodBinding[] methods = currentType.availableMethods();
2620        if(methods != null) {
2621            next : for (int f = methods.length; --f >= 0;) {
2622                MethodBinding constructor = methods[f];
2623                if (constructor != enclosingConstructor && constructor.isConstructor()) {
2624                    
2625                    if (constructor.isSynthetic()) continue next;
2626                        
2627                    if (this.options.checkDeprecation &&
2628                            constructor.isViewedAsDeprecated() &&
2629                            !scope.isDefinedInSameUnit(constructor.declaringClass))
2630                        continue next;
2631                    
2632                    if (this.options.checkVisibility
2633                        && !constructor.canBeSeenBy(invocationSite, scope)) continue next;
2634                    
2635                    TypeBinding[] parameters = constructor.parameters;
2636                    int paramLength = parameters.length;
2637    
2638                    char[][] parameterPackageNames = new char[paramLength][];
2639                    char[][] parameterTypeNames = new char[paramLength][];
2640                    for (int i = 0; i < paramLength; i++) {
2641                        TypeBinding type = parameters[i];
2642                        parameterPackageNames[i] = type.qualifiedPackageName();
2643                        parameterTypeNames[i] = type.qualifiedSourceName();
2644                    }
2645                    char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);
2646                    
2647                    char[] completion = CharOperation.NO_CHAR;
2648                    if (this.source != null
2649                        && this.source.length > this.endPosition
2650                        && this.source[this.endPosition] == '(')
2651                        completion = name;
2652                    else
2653                        completion = CharOperation.concat(name, new char[] { '(', ')' });
2654                    
2655                    int relevance = computeBaseRelevance();
2656                    relevance += computeRelevanceForResolution();
2657                    relevance += computeRelevanceForInterestingProposal();
2658                    relevance += computeRelevanceForCaseMatching(this.completionToken, name);
2659                    relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
2660                    
2661                    this.noProposal = false;
2662                    if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
2663                        CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
2664                        proposal.setDeclarationSignature(getSignature(currentType));
2665                        proposal.setSignature(getSignature(constructor));
2666                        MethodBinding original = constructor.original();
2667                        if(original != constructor) {
2668                            proposal.setOriginalSignature(getSignature(original));
2669                        }
2670                        proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
2671                        proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
2672                        proposal.setParameterPackageNames(parameterPackageNames);
2673                        proposal.setParameterTypeNames(parameterTypeNames);
2674                        //proposal.setPackageName(null);
2675
//proposal.setTypeName(null);
2676
proposal.setName(name);
2677                        proposal.setIsContructor(true);
2678                        proposal.setCompletion(completion);
2679                        proposal.setFlags(constructor.modifiers);
2680                        proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
2681                        proposal.setRelevance(relevance);
2682                        if(parameterNames != null) proposal.setParameterNames(parameterNames);
2683                        this.requestor.accept(proposal);
2684                        if(DEBUG) {
2685                            this.printDebug(proposal);
2686                        }
2687                    }
2688                }
2689            }
2690        }
2691    }
2692    private void findConstructors(
2693        ReferenceBinding currentType,
2694        TypeBinding[] argTypes,
2695        Scope scope,
2696        InvocationSite invocationSite,
2697        boolean forAnonymousType) {
2698
2699        // No visibility checks can be performed without the scope & invocationSite
2700
MethodBinding[] methods = currentType.availableMethods();
2701        if(methods != null) {
2702            int minArgLength = argTypes == null ? 0 : argTypes.length;
2703            next : for (int f = methods.length; --f >= 0;) {
2704                MethodBinding constructor = methods[f];
2705                if (constructor.isConstructor()) {
2706                    
2707                    if (constructor.isSynthetic()) continue next;
2708                        
2709                    if (this.options.checkDeprecation &&
2710                            constructor.isViewedAsDeprecated() &&
2711                            !scope.isDefinedInSameUnit(constructor.declaringClass))
2712                        continue next;
2713                    
2714                    if (this.options.checkVisibility
2715                        && !constructor.canBeSeenBy(invocationSite, scope)) {
2716                        if(!forAnonymousType || !constructor.isProtected())
2717                            continue next;
2718                    }
2719                    
2720                    TypeBinding[] parameters = constructor.parameters;
2721                    int paramLength = parameters.length;
2722                    if (minArgLength > paramLength)
2723                        continue next;
2724                    for (int a = minArgLength; --a >= 0;)
2725                        if (argTypes[a] != null) { // can be null if it could not be resolved properly
2726
if (!argTypes[a].isCompatibleWith(constructor.parameters[a]))
2727                                continue next;
2728                        }
2729    
2730                    char[][] parameterPackageNames = new char[paramLength][];
2731                    char[][] parameterTypeNames = new char[paramLength][];
2732                    for (int i = 0; i < paramLength; i++) {
2733                        TypeBinding type = parameters[i];
2734                        parameterPackageNames[i] = type.qualifiedPackageName();
2735                        parameterTypeNames[i] = type.qualifiedSourceName();
2736                    }
2737                    char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);
2738                    
2739                    char[] completion = CharOperation.NO_CHAR;
2740                    if(forAnonymousType){
2741                        int relevance = computeBaseRelevance();
2742                        relevance += computeRelevanceForResolution();
2743                        relevance += computeRelevanceForInterestingProposal();
2744                        relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
2745                        
2746                        this.noProposal = false;
2747                        if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
2748                            CompletionProposal proposal = this.createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
2749                            proposal.setDeclarationSignature(getSignature(currentType));
2750                            proposal.setDeclarationKey(currentType.computeUniqueKey());
2751                            proposal.setSignature(getSignature(constructor));
2752                            MethodBinding original = constructor.original();
2753                            if(original != constructor) {
2754                                proposal.setOriginalSignature(getSignature(original));
2755                            }
2756                            proposal.setKey(constructor.computeUniqueKey());
2757                            proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
2758                            proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
2759                            proposal.setParameterPackageNames(parameterPackageNames);
2760                            proposal.setParameterTypeNames(parameterTypeNames);
2761                            //proposal.setPackageName(null);
2762
//proposal.setTypeName(null);
2763
proposal.setCompletion(completion);
2764                            proposal.setFlags(constructor.modifiers);
2765                            proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
2766                            proposal.setRelevance(relevance);
2767                            if(parameterNames != null) proposal.setParameterNames(parameterNames);
2768                            this.requestor.accept(proposal);
2769                            if(DEBUG) {
2770                                this.printDebug(proposal);
2771                            }
2772                        }
2773                    } else {
2774                        int relevance = computeBaseRelevance();
2775                        relevance += computeRelevanceForResolution();
2776                        relevance += computeRelevanceForInterestingProposal();
2777                        relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
2778
2779                        // Special case for completion in javadoc
2780
if (this.assistNodeInJavadoc > 0) {
2781                            Expression receiver = null;
2782                            char[] selector = null;
2783                            if (invocationSite instanceof CompletionOnJavadocAllocationExpression) {
2784                                CompletionOnJavadocAllocationExpression alloc = (CompletionOnJavadocAllocationExpression) invocationSite;
2785                                receiver = alloc.type;
2786                            } else if (invocationSite instanceof CompletionOnJavadocFieldReference) {
2787                                CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
2788                                receiver = fieldRef.receiver;
2789                            }
2790                            if (receiver != null) {
2791                                StringBuffer JavaDoc javadocCompletion = new StringBuffer JavaDoc();
2792                                if (receiver.isThis()) {
2793                                    selector = (((JavadocImplicitTypeReference)receiver).token);
2794                                    if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
2795                                        javadocCompletion.append('#');
2796                                    }
2797                                } else if (receiver instanceof JavadocSingleTypeReference) {
2798                                    JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver;
2799                                    selector = typeRef.token;
2800                                    if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
2801                                        javadocCompletion.append(typeRef.token);
2802                                        javadocCompletion.append('#');
2803                                    }
2804                                } else if (receiver instanceof JavadocQualifiedTypeReference) {
2805                                    JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver;
2806                                    selector = typeRef.tokens[typeRef.tokens.length-1];
2807                                    if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
2808                                        javadocCompletion.append(CharOperation.concatWith(typeRef.tokens, '.'));
2809                                        javadocCompletion.append('#');
2810                                    }
2811                                }
2812                                // Append parameters types
2813
javadocCompletion.append(selector);
2814                                javadocCompletion.append('(');
2815                                if (constructor.parameters != null) {
2816                                    boolean isVarargs = constructor.isVarargs();
2817                                    for (int p=0, ln=constructor.parameters.length; p<ln; p++) {
2818                                        if (p>0) javadocCompletion.append(", "); //$NON-NLS-1$
2819
TypeBinding argTypeBinding = constructor.parameters[p];
2820                                        if (isVarargs && p == ln - 1) {
2821                                            createVargsType(argTypeBinding.erasure(), javadocCompletion);
2822                                        } else {
2823                                            createType(argTypeBinding.erasure(), javadocCompletion);
2824                                        }
2825                                    }
2826                                }
2827                                javadocCompletion.append(')');
2828                                completion = javadocCompletion.toString().toCharArray();
2829                            }
2830                        }
2831                        
2832                        // Create standard proposal
2833
this.noProposal = false;
2834                        if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
2835                            CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
2836                            proposal.setDeclarationSignature(getSignature(currentType));
2837                            proposal.setSignature(getSignature(constructor));
2838                            MethodBinding original = constructor.original();
2839                            if(original != constructor) {
2840                                proposal.setOriginalSignature(getSignature(original));
2841                            }
2842                            proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
2843                            proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
2844                            proposal.setParameterPackageNames(parameterPackageNames);
2845                            proposal.setParameterTypeNames(parameterTypeNames);
2846                            //proposal.setPackageName(null);
2847
//proposal.setTypeName(null);
2848
proposal.setName(currentType.sourceName());
2849                            proposal.setIsContructor(true);
2850                            proposal.setCompletion(completion);
2851                            proposal.setFlags(constructor.modifiers);
2852                            int start = (this.assistNodeInJavadoc > 0) ? this.startPosition : this.endPosition;
2853                            proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
2854                            proposal.setRelevance(relevance);
2855                            if(parameterNames != null) proposal.setParameterNames(parameterNames);
2856                            this.requestor.accept(proposal);
2857                            if(DEBUG) {
2858                                this.printDebug(proposal);
2859                            }
2860                        }
2861                        if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
2862                            char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
2863                            CompletionProposal proposal = this.createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition);
2864                            proposal.setDeclarationSignature(getSignature(currentType));
2865                            proposal.setSignature(getSignature(constructor));
2866                            MethodBinding original = constructor.original();
2867                            if(original != constructor) {
2868                                proposal.setOriginalSignature(getSignature(original));
2869                            }
2870                            proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
2871                            proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
2872                            proposal.setParameterPackageNames(parameterPackageNames);
2873                            proposal.setParameterTypeNames(parameterTypeNames);
2874                            //proposal.setPackageName(null);
2875
//proposal.setTypeName(null);
2876
proposal.setName(currentType.sourceName());
2877                            proposal.setIsContructor(true);
2878                            proposal.setCompletion(javadocCompletion);
2879                            proposal.setFlags(constructor.modifiers);
2880                            int start = (this.assistNodeInJavadoc > 0) ? this.startPosition : this.endPosition;
2881                            if ((this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0) start = this.javadocTagPosition;
2882                            proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
2883                            proposal.setRelevance(relevance+R_INLINE_TAG);
2884                            if(parameterNames != null) proposal.setParameterNames(parameterNames);
2885                            this.requestor.accept(proposal);
2886                            if(DEBUG) {
2887                                this.printDebug(proposal);
2888                            }
2889                        }
2890                    }
2891                }
2892            }
2893        }
2894    }
2895    
2896    private char[][] findEnclosingTypeNames(Scope scope){
2897        char[][] excludedNames = new char[10][];
2898        int excludedNameCount = 0;
2899        
2900        Scope currentScope = scope;
2901        while(currentScope != null) {
2902            switch (currentScope.kind) {
2903                case Scope.CLASS_SCOPE :
2904                    ClassScope classScope = (ClassScope) currentScope;
2905                    
2906                    TypeDeclaration typeDeclaration = classScope.referenceContext;
2907                    
2908                    if(excludedNameCount == excludedNames.length) {
2909                        System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
2910                    }
2911                    excludedNames[excludedNameCount++] = typeDeclaration.name;
2912                    
2913                    TypeParameter[] classTypeParameters = typeDeclaration.typeParameters;
2914                    if(classTypeParameters != null) {
2915                        for (int i = 0; i < classTypeParameters.length; i++) {
2916                            TypeParameter typeParameter = classTypeParameters[i];
2917                            if(excludedNameCount == excludedNames.length) {
2918                                System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
2919                            }
2920                            excludedNames[excludedNameCount++] = typeParameter.name;
2921                        }
2922                    }
2923                    break;
2924                case Scope.METHOD_SCOPE :
2925                    MethodScope methodScope = (MethodScope) currentScope;
2926                    if(methodScope.referenceContext instanceof AbstractMethodDeclaration) {
2927                        TypeParameter[] methodTypeParameters = ((AbstractMethodDeclaration)methodScope.referenceContext).typeParameters();
2928                        if(methodTypeParameters != null) {
2929                            for (int i = 0; i < methodTypeParameters.length; i++) {
2930                                TypeParameter typeParameter = methodTypeParameters[i];
2931                                if(excludedNameCount == excludedNames.length) {
2932                                    System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
2933                                }
2934                                excludedNames[excludedNameCount++] = typeParameter.name;
2935                            }
2936                        }
2937                    }
2938                    break;
2939            }
2940            
2941            currentScope = currentScope.parent;
2942        }
2943        
2944        if(excludedNameCount == 0) {
2945            return CharOperation.NO_CHAR_CHAR;
2946        }
2947        System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount][], 0, excludedNameCount);
2948        return excludedNames;
2949    }
2950    
2951    // Helper method for findFields(char[], ReferenceBinding, Scope, ObjectVector, boolean)
2952
private void findFields(
2953        char[] fieldName,
2954        FieldBinding[] fields,
2955        Scope scope,
2956        ObjectVector fieldsFound,
2957        ObjectVector localsFound,
2958        boolean onlyStaticFields,
2959        ReferenceBinding receiverType,
2960        InvocationSite invocationSite,
2961        Scope invocationScope,
2962        boolean implicitCall,
2963        boolean canBePrefixed,
2964        Binding[] missingElements,
2965        int[] missingElementsStarts,
2966        int[] missingElementsEnds,
2967        boolean missingElementsHaveProblems) {
2968
2969        ObjectVector newFieldsFound = new ObjectVector();
2970        // Inherited fields which are hidden by subclasses are filtered out
2971
// No visibility checks can be performed without the scope & invocationSite
2972

2973        int fieldLength = fieldName.length;
2974        next : for (int f = fields.length; --f >= 0;) {
2975            FieldBinding field = fields[f];
2976
2977            if (field.isSynthetic()) continue next;
2978            
2979            if (onlyStaticFields && !field.isStatic()) continue next;
2980
2981            if (fieldLength > field.name.length) continue next;
2982
2983            if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)
2984                    && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name))) continue next;
2985
2986            if (this.options.checkDeprecation &&
2987                    field.isViewedAsDeprecated() &&
2988                    !scope.isDefinedInSameUnit(field.declaringClass))
2989                continue next;
2990            
2991            if (this.options.checkVisibility
2992                && !field.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
2993
2994            boolean prefixRequired = false;
2995
2996            for (int i = fieldsFound.size; --i >= 0;) {
2997                Object JavaDoc[] other = (Object JavaDoc[])fieldsFound.elementAt(i);
2998                FieldBinding otherField = (FieldBinding) other[0];
2999                ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
3000                if (field == otherField && receiverType == otherReceiverType)
3001                    continue next;
3002                if (CharOperation.equals(field.name, otherField.name, true)) {
3003                    if (field.declaringClass.isSuperclassOf(otherField.declaringClass))
3004                        continue next;
3005                    if (otherField.declaringClass.isInterface()) {
3006                        if (field.declaringClass == scope.getJavaLangObject())
3007                            continue next;
3008                        if (field.declaringClass.implementsInterface(otherField.declaringClass, true))
3009                            continue next;
3010                    }
3011                    if (field.declaringClass.isInterface())
3012                        if (otherField.declaringClass.implementsInterface(field.declaringClass, true))
3013                            continue next;
3014                    if(canBePrefixed) {
3015                        prefixRequired = true;
3016                    } else {
3017                        continue next;
3018                    }
3019                }
3020            }
3021
3022            for (int l = localsFound.size; --l >= 0;) {
3023                LocalVariableBinding local = (LocalVariableBinding) localsFound.elementAt(l);
3024
3025                if (CharOperation.equals(field.name, local.name, true)) {
3026                    SourceTypeBinding declarationType = scope.enclosingSourceType();
3027                    if (declarationType.isAnonymousType() && declarationType != invocationScope.enclosingSourceType()) {
3028                        continue next;
3029                    }
3030                    if(canBePrefixed) {
3031                        prefixRequired = true;
3032                    } else {
3033                        continue next;
3034                    }
3035                    break;
3036                }
3037            }
3038            
3039            newFieldsFound.add(new Object JavaDoc[]{field, receiverType});
3040            
3041            char[] completion = field.name;
3042            
3043            if(prefixRequired || this.options.forceImplicitQualification){
3044                char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), field.isStatic());
3045                completion = CharOperation.concat(prefix,completion,'.');
3046            }
3047
3048            // Special case for javadoc completion
3049
if (this.assistNodeInJavadoc > 0) {
3050                if (invocationSite instanceof CompletionOnJavadocFieldReference) {
3051                    CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
3052                    if (fieldRef.receiver.isThis()) {
3053                        if (fieldRef.completeInText()) {
3054                            completion = CharOperation.concat(new char[] { '#' }, field.name);
3055                        }
3056                    } else if (fieldRef.completeInText()) {
3057                        if (fieldRef.receiver instanceof JavadocSingleTypeReference) {
3058                            JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) fieldRef.receiver;
3059                            completion = CharOperation.concat(typeRef.token, field.name, '#');
3060                        } else if (fieldRef.receiver instanceof JavadocQualifiedTypeReference) {
3061                            JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) fieldRef.receiver;
3062                            completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), field.name, '#');
3063                        }
3064                    }
3065                }
3066            }
3067
3068            int relevance = computeBaseRelevance();
3069            relevance += computeRelevanceForResolution();
3070            relevance += computeRelevanceForInterestingProposal(field);
3071            if (fieldName != null) relevance += computeRelevanceForCaseMatching(fieldName, field.name);
3072            relevance += computeRelevanceForExpectingType(field.type);
3073            relevance += computeRelevanceForStatic(onlyStaticFields, field.isStatic());
3074            relevance += computeRelevanceForQualification(prefixRequired);
3075            relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
3076            if (onlyStaticFields && this.insideQualifiedReference) {
3077                relevance += computeRelevanceForInheritance(receiverType, field.declaringClass);
3078            }
3079            if (missingElements != null) {
3080                relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
3081            }
3082            
3083            this.noProposal = false;
3084            // Standard proposal
3085
if (!this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
3086                CompletionProposal proposal = this.createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
3087                proposal.setDeclarationSignature(getSignature(field.declaringClass));
3088                proposal.setSignature(getSignature(field.type));
3089                proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
3090                proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
3091                proposal.setPackageName(field.type.qualifiedPackageName());
3092                proposal.setTypeName(field.type.qualifiedSourceName());
3093                proposal.setName(field.name);
3094                if (missingElements != null) {
3095                    CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
3096                    for (int i = 0; i < missingElements.length; i++) {
3097                        subProposals[i] =
3098                            createRequiredTypeProposal(
3099                                    missingElements[i],
3100                                    missingElementsStarts[i],
3101                                    missingElementsEnds[i],
3102                                    relevance);
3103                    }
3104                    proposal.setRequiredProposals(subProposals);
3105                }
3106                proposal.setCompletion(completion);
3107                proposal.setFlags(field.modifiers);
3108                proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3109                proposal.setRelevance(relevance);
3110                this.requestor.accept(proposal);
3111                if(DEBUG) {
3112                    this.printDebug(proposal);
3113                }
3114            }
3115
3116            // Javadoc completions
3117
if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) {
3118                char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
3119                CompletionProposal proposal = this.createProposal(CompletionProposal.JAVADOC_FIELD_REF, this.actualCompletionPosition);
3120                proposal.setDeclarationSignature(getSignature(field.declaringClass));
3121                proposal.setSignature(getSignature(field.type));
3122                proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
3123                proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
3124                proposal.setPackageName(field.type.qualifiedPackageName());
3125                proposal.setTypeName(field.type.qualifiedSourceName());
3126                proposal.setName(field.name);
3127                proposal.setCompletion(javadocCompletion);
3128                proposal.setFlags(field.modifiers);
3129                int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
3130                proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
3131                proposal.setRelevance(relevance+R_INLINE_TAG);
3132                this.requestor.accept(proposal);
3133                if(DEBUG) {
3134                    this.printDebug(proposal);
3135                }
3136                // Javadoc value completion for static fields
3137
if (field.isStatic() && !this.requestor.isIgnored(CompletionProposal.JAVADOC_VALUE_REF)) {
3138                    javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_VALUE);
3139                    CompletionProposal valueProposal = this.createProposal(CompletionProposal.JAVADOC_VALUE_REF, this.actualCompletionPosition);
3140                    valueProposal.setDeclarationSignature(getSignature(field.declaringClass));
3141                    valueProposal.setSignature(getSignature(field.type));
3142                    valueProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
3143                    valueProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
3144                    valueProposal.setPackageName(field.type.qualifiedPackageName());
3145                    valueProposal.setTypeName(field.type.qualifiedSourceName());
3146                    valueProposal.setName(field.name);
3147                    valueProposal.setCompletion(javadocCompletion);
3148                    valueProposal.setFlags(field.modifiers);
3149                    valueProposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
3150                    valueProposal.setRelevance(relevance+R_VALUE_TAG);
3151                    this.requestor.accept(valueProposal);
3152                    if(DEBUG) {
3153                        this.printDebug(valueProposal);
3154                    }
3155                }
3156            }
3157        }
3158        
3159        fieldsFound.addAll(newFieldsFound);
3160    }
3161
3162    private void findFields(
3163        char[] fieldName,
3164        ReferenceBinding receiverType,
3165        Scope scope,
3166        ObjectVector fieldsFound,
3167        ObjectVector localsFound,
3168        boolean onlyStaticFields,
3169        InvocationSite invocationSite,
3170        Scope invocationScope,
3171        boolean implicitCall,
3172        boolean canBePrefixed,
3173        Binding[] missingElements,
3174        int[] missingElementsStarts,
3175        int[] missingElementsEnds,
3176        boolean missingElementsHaveProblems) {
3177
3178        boolean notInJavadoc = this.assistNodeInJavadoc == 0;
3179        if (fieldName == null && notInJavadoc)
3180            return;
3181
3182        ReferenceBinding currentType = receiverType;
3183        ReferenceBinding[] interfacesToVisit = null;
3184        int nextPosition = 0;
3185        do {
3186            ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
3187            if (notInJavadoc && itsInterfaces != Binding.NO_SUPERINTERFACES) {
3188                if (interfacesToVisit == null) {
3189                    interfacesToVisit = itsInterfaces;
3190                    nextPosition = interfacesToVisit.length;
3191                } else {
3192                    int itsLength = itsInterfaces.length;
3193                    if (nextPosition + itsLength >= interfacesToVisit.length)
3194                        System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
3195                    nextInterface : for (int a = 0; a < itsLength; a++) {
3196                        ReferenceBinding next = itsInterfaces[a];
3197                        for (int b = 0; b < nextPosition; b++)
3198                            if (next == interfacesToVisit[b]) continue nextInterface;
3199                        interfacesToVisit[nextPosition++] = next;
3200                    }
3201                }
3202            }
3203
3204            FieldBinding[] fields = currentType.availableFields();
3205            if(fields != null && fields.length > 0) {
3206                findFields(
3207                    fieldName,
3208                    fields,
3209                    scope,
3210                    fieldsFound,
3211                    localsFound,
3212                    onlyStaticFields,
3213                    receiverType,
3214                    invocationSite,
3215                    invocationScope,
3216                    implicitCall,
3217                    canBePrefixed,
3218                    missingElements,
3219                    missingElementsStarts,
3220                    missingElementsEnds,
3221                    missingElementsHaveProblems);
3222            }
3223            currentType = currentType.superclass();
3224        } while (notInJavadoc && currentType != null);
3225
3226        if (notInJavadoc && interfacesToVisit != null) {
3227            for (int i = 0; i < nextPosition; i++) {
3228                ReferenceBinding anInterface = interfacesToVisit[i];
3229                FieldBinding[] fields = anInterface.availableFields();
3230                if(fields != null) {
3231                    findFields(
3232                        fieldName,
3233                        fields,
3234                        scope,
3235                        fieldsFound,
3236                        localsFound,
3237                        onlyStaticFields,
3238                        receiverType,
3239                        invocationSite,
3240                        invocationScope,
3241                        implicitCall,
3242                        canBePrefixed,
3243                        missingElements,
3244                        missingElementsStarts,
3245                        missingElementsEnds,
3246                        missingElementsHaveProblems);
3247                }
3248
3249                ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
3250                if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
3251                    int itsLength = itsInterfaces.length;
3252                    if (nextPosition + itsLength >= interfacesToVisit.length)
3253                        System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
3254                    nextInterface : for (int a = 0; a < itsLength; a++) {
3255                        ReferenceBinding next = itsInterfaces[a];
3256                        for (int b = 0; b < nextPosition; b++)
3257                            if (next == interfacesToVisit[b]) continue nextInterface;
3258                        interfacesToVisit[nextPosition++] = next;
3259                    }
3260                }
3261            }
3262        }
3263    }
3264
3265    protected void findFieldsAndMethods(
3266        char[] token,
3267        TypeBinding receiverType,
3268        Scope scope,
3269        InvocationSite invocationSite,
3270        Scope invocationScope,
3271        boolean implicitCall,
3272        boolean superCall,
3273        Binding[] missingElements,
3274        int[] missingElementsStarts,
3275        int[] missingElementsEnds,
3276        boolean missingElementsHaveProblems) {
3277
3278        if (token == null)
3279            return;
3280
3281        if (receiverType.isBaseType())
3282            return; // nothing else is possible with base types
3283

3284        boolean proposeField = !this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null);
3285        boolean proposeMethod = !this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null);
3286        
3287        ObjectVector methodsFound = new ObjectVector();
3288        
3289        if (receiverType.isArrayType()) {
3290            if (proposeField
3291                && token.length <= lengthField.length
3292                && CharOperation.prefixEquals(token, lengthField, false /* ignore case */
3293            )) {
3294                
3295                int relevance = computeBaseRelevance();
3296                relevance += computeRelevanceForResolution();
3297                relevance += computeRelevanceForInterestingProposal();
3298                relevance += computeRelevanceForCaseMatching(token,lengthField);
3299                relevance += computeRelevanceForExpectingType(TypeBinding.INT);
3300                relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for length field
3301
if (missingElements != null) {
3302                    relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
3303                }
3304                this.noProposal = false;
3305                if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) {
3306                    CompletionProposal proposal = this.createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
3307                    proposal.setDeclarationSignature(getSignature(receiverType));
3308                    proposal.setSignature(INT_SIGNATURE);
3309                    //proposal.setDeclarationPackageName(null);
3310
//proposal.setDeclarationTypeName(null);
3311
//proposal.setPackageName(null);
3312
proposal.setTypeName(INT);
3313                    proposal.setName(lengthField);
3314                    if (missingElements != null) {
3315                        CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
3316                        for (int i = 0; i < missingElements.length; i++) {
3317                            subProposals[i] =
3318                                createRequiredTypeProposal(
3319                                        missingElements[i],
3320                                        missingElementsStarts[i],
3321                                        missingElementsEnds[i],
3322                                        relevance);
3323                        }
3324                        proposal.setRequiredProposals(subProposals);
3325                    }
3326                    proposal.setCompletion(lengthField);
3327                    proposal.setFlags(Flags.AccPublic);
3328                    proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3329                    proposal.setRelevance(relevance);
3330                    this.requestor.accept(proposal);
3331                    if(DEBUG) {
3332                        this.printDebug(proposal);
3333                    }
3334                }
3335            }
3336            if (proposeMethod
3337                && token.length <= cloneMethod.length
3338                && CharOperation.prefixEquals(token, cloneMethod, false /* ignore case */)
3339            ) {
3340                ReferenceBinding objectRef = scope.getJavaLangObject();
3341                
3342                int relevance = computeBaseRelevance();
3343                relevance += computeRelevanceForResolution();
3344                relevance += computeRelevanceForInterestingProposal();
3345                relevance += computeRelevanceForCaseMatching(token, cloneMethod);
3346                relevance += computeRelevanceForExpectingType(objectRef);
3347                relevance += computeRelevanceForStatic(false, false);
3348                relevance += computeRelevanceForQualification(false);
3349                relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for clone() method
3350
if (missingElements != null) {
3351                    relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
3352                }
3353                char[] completion;
3354                if (this.source != null
3355                    && this.source.length > this.endPosition
3356                    && this.source[this.endPosition] == '(') {
3357                    completion = cloneMethod;
3358                    } else {
3359                    completion = CharOperation.concat(cloneMethod, new char[] { '(', ')' });
3360                }
3361                this.noProposal = false;
3362                if (!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null)) {
3363                    CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
3364                    proposal.setDeclarationSignature(getSignature(receiverType));
3365                    proposal.setSignature(
3366                            this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ?
3367                                    createMethodSignature(
3368                                            CharOperation.NO_CHAR_CHAR,
3369                                            CharOperation.NO_CHAR_CHAR,
3370                                            getSignature(receiverType)) :
3371                                    createMethodSignature(
3372                                            CharOperation.NO_CHAR_CHAR,
3373                                            CharOperation.NO_CHAR_CHAR,
3374                                            CharOperation.concatWith(JAVA_LANG, '.'),
3375                                            OBJECT));
3376                    //proposal.setOriginalSignature(null);
3377
//proposal.setDeclarationPackageName(null);
3378
//proposal.setDeclarationTypeName(null);
3379
//proposal.setParameterPackageNames(null);
3380
//proposal.setParameterTypeNames(null);
3381
proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
3382                    proposal.setTypeName(OBJECT);
3383                    proposal.setName(cloneMethod);
3384                    if (missingElements != null) {
3385                        CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
3386                        for (int i = 0; i < missingElements.length; i++) {
3387                            subProposals[i] =
3388                                createRequiredTypeProposal(
3389                                        missingElements[i],
3390                                        missingElementsStarts[i],
3391                                        missingElementsEnds[i],
3392                                        relevance);
3393                        }
3394                        proposal.setRequiredProposals(subProposals);
3395                    }
3396                    proposal.setCompletion(completion);
3397                    proposal.setFlags(Flags.AccPublic);
3398                    proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3399                    proposal.setRelevance(relevance);
3400                    this.requestor.accept(proposal);
3401                    if(DEBUG) {
3402                        this.printDebug(proposal);
3403                    }
3404                }
3405                methodsFound.add(new Object JavaDoc[]{objectRef.getMethods(cloneMethod)[0], objectRef});
3406            }
3407            
3408            receiverType = scope.getJavaLangObject();
3409        }
3410
3411        if(proposeField) {
3412            findFields(
3413                token,
3414                (ReferenceBinding) receiverType,
3415                scope,
3416                new ObjectVector(),
3417                new ObjectVector(),
3418                false,
3419                invocationSite,
3420                invocationScope,
3421                implicitCall,
3422                false,
3423                missingElements,
3424                missingElementsStarts,
3425                missingElementsEnds,
3426                missingElementsHaveProblems);
3427        }
3428
3429        if(proposeMethod) {
3430            findMethods(
3431                token,
3432                null,
3433                null,
3434                (ReferenceBinding) receiverType,
3435                scope,
3436                methodsFound,
3437                false,
3438                false,
3439                false,
3440                invocationSite,
3441                invocationScope,
3442                implicitCall,
3443                superCall,
3444                false,
3445                missingElements,
3446                missingElementsStarts,
3447                missingElementsEnds,
3448                missingElementsHaveProblems);
3449        }
3450    }
3451    
3452    private void findFieldsAndMethodsFromFavorites(
3453            char[] token,
3454            Scope scope,
3455            InvocationSite invocationSite,
3456            Scope invocationScope,
3457            ObjectVector localsFound,
3458            ObjectVector fieldsFound,
3459            ObjectVector methodsFound) {
3460        
3461        ImportBinding[] favoriteBindings = getFavoriteReferenceBindings(invocationScope);
3462        
3463        if (favoriteBindings != null && favoriteBindings.length > 0) {
3464            for (int i = 0; i < favoriteBindings.length; i++) {
3465                ImportBinding favoriteBinding = favoriteBindings[i];
3466                switch (favoriteBinding.resolvedImport.kind()) {
3467                    case Binding.FIELD:
3468                        FieldBinding fieldBinding = (FieldBinding) favoriteBinding.resolvedImport;
3469                        findFieldsFromFavorites(
3470                                token,
3471                                new FieldBinding[]{fieldBinding},
3472                                scope,
3473                                fieldsFound,
3474                                localsFound,
3475                                fieldBinding.declaringClass,
3476                                invocationSite,
3477                                invocationScope);
3478                        break;
3479                    case Binding.METHOD:
3480                        MethodBinding methodBinding = (MethodBinding) favoriteBinding.resolvedImport;
3481                        MethodBinding[] methods = methodBinding.declaringClass.availableMethods();
3482                        long range;
3483                        if ((range = ReferenceBinding.binarySearch(methodBinding.selector, methods)) >= 0) {
3484                            int start = (int) range, end = (int) (range >> 32);
3485                            int length = end - start + 1;
3486                            System.arraycopy(methods, start, methods = new MethodBinding[length], 0, length);
3487                        } else {
3488                            methods = Binding.NO_METHODS;
3489                        }
3490                        findLocalMethodsFromFavorites(
3491                                token,
3492                                methods,
3493                                scope,
3494                                methodsFound,
3495                                methodBinding.declaringClass,
3496                                invocationSite,
3497                                invocationScope);
3498                        break;
3499                    case Binding.TYPE:
3500                        ReferenceBinding referenceBinding = (ReferenceBinding) favoriteBinding.resolvedImport;
3501                        if(favoriteBinding.onDemand) {
3502                            findFieldsFromFavorites(
3503                                    token,
3504                                    referenceBinding.availableFields(),
3505                                    scope,
3506                                    fieldsFound,
3507                                    localsFound,
3508                                    referenceBinding,
3509                                    invocationSite,
3510                                    invocationScope);
3511                            
3512                            findLocalMethodsFromFavorites(
3513                                    token,
3514                                    referenceBinding.availableMethods(),
3515                                    scope,
3516                                    methodsFound,
3517                                    referenceBinding,
3518                                    invocationSite,
3519                                    invocationScope);
3520                        }
3521                        break;
3522                }
3523            }
3524        }
3525    }
3526    
3527    private void findFieldsAndMethodsFromMissingFieldType(
3528        char[] token,
3529        Scope scope,
3530        InvocationSite invocationSite,
3531        boolean insideTypeAnnotation) {
3532
3533        boolean staticsOnly = false;
3534        Scope currentScope = scope;
3535
3536        done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
3537

3538            switch (currentScope.kind) {
3539
3540                case Scope.METHOD_SCOPE :
3541                    // handle the error case inside an explicit constructor call (see MethodScope>>findField)
3542
MethodScope methodScope = (MethodScope) currentScope;
3543                    staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
3544
3545                case Scope.BLOCK_SCOPE :
3546                    break;
3547
3548                case Scope.CLASS_SCOPE :
3549                    ClassScope classScope = (ClassScope) currentScope;
3550                    SourceTypeBinding enclosingType = classScope.referenceContext.binding;
3551                    if(!insideTypeAnnotation) {
3552                        
3553                        FieldDeclaration[] fields = classScope.referenceContext.fields;
3554                        
3555                        int fieldsCount = fields == null ? 0 : fields.length;
3556                        for (int i = 0; i < fieldsCount; i++) {
3557                            FieldDeclaration fieldDeclaration = fields[i];
3558                            if (CharOperation.equals(fieldDeclaration.name, token)) {
3559                                if (fieldDeclaration.binding == null) {
3560                                    findFieldsAndMethodsFromMissingType(
3561                                            this.completionToken,
3562                                            fieldDeclaration.type,
3563                                            currentScope,
3564                                            invocationSite,
3565                                            scope);
3566                                }
3567                                break done;
3568                            }
3569                        }
3570                    }
3571                    staticsOnly |= enclosingType.isStatic();
3572                    insideTypeAnnotation = false;
3573                    break;
3574                case Scope.COMPILATION_UNIT_SCOPE :
3575                    break done;
3576            }
3577            currentScope = currentScope.parent;
3578        }
3579    }
3580    
3581    private void findFieldsAndMethodsFromMissingReturnType(
3582        char[] token,
3583        TypeBinding[] arguments,
3584        Scope scope,
3585        InvocationSite invocationSite,
3586        boolean insideTypeAnnotation) {
3587
3588        boolean staticsOnly = false;
3589        Scope currentScope = scope;
3590
3591        done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
3592

3593            switch (currentScope.kind) {
3594
3595                case Scope.METHOD_SCOPE :
3596                    // handle the error case inside an explicit constructor call (see MethodScope>>findField)
3597
MethodScope methodScope = (MethodScope) currentScope;
3598                    staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
3599
3600                case Scope.BLOCK_SCOPE :
3601                    break;
3602
3603                case Scope.CLASS_SCOPE :
3604                    ClassScope classScope = (ClassScope) currentScope;
3605                    SourceTypeBinding enclosingType = classScope.referenceContext.binding;
3606                    if(!insideTypeAnnotation) {
3607                        
3608                        AbstractMethodDeclaration[] methods = classScope.referenceContext.methods;
3609                        
3610                        int methodsCount = methods == null ? 0 : methods.length;
3611                        for (int i = 0; i < methodsCount; i++) {
3612                            AbstractMethodDeclaration methodDeclaration = methods[i];
3613                            if (methodDeclaration instanceof MethodDeclaration &&
3614                                    CharOperation.equals(methodDeclaration.selector, token)) {
3615                                MethodDeclaration method = (MethodDeclaration) methodDeclaration;
3616                                if (methodDeclaration.binding == null) {
3617                                    Argument[] parameters = method.arguments;
3618                                    int parametersLength = parameters == null ? 0 : parameters.length;
3619                                    int argumentsLength = arguments == null ? 0 : arguments.length;
3620                                    
3621                                    if (parametersLength == 0) {
3622                                        if (argumentsLength == 0) {
3623                                            findFieldsAndMethodsFromMissingType(
3624                                                    this.completionToken,
3625                                                    method.returnType,
3626                                                    currentScope,
3627                                                    invocationSite,
3628                                                    scope);
3629                                            break done;
3630                                        }
3631                                    } else {
3632                                        TypeBinding[] parametersBindings = new TypeBinding[parametersLength];
3633                                        for (int j = 0; j < parametersLength; j++) {
3634                                            parametersBindings[j] = parameters[j].type.resolvedType;
3635                                        }
3636                                        if(areParametersCompatibleWith(parametersBindings, arguments, parameters[parametersLength - 1].isVarArgs())) {
3637                                            findFieldsAndMethodsFromMissingType(
3638                                                    this.completionToken,
3639                                                    method.returnType,
3640                                                    currentScope,
3641                                                    invocationSite,
3642                                                    scope);
3643                                            break done;
3644                                        }
3645                                    }
3646                                }
3647                                
3648                            }
3649                        }
3650                    }
3651                    staticsOnly |= enclosingType.isStatic();
3652                    insideTypeAnnotation = false;
3653                    break;
3654                case Scope.COMPILATION_UNIT_SCOPE :
3655                    break done;
3656            }
3657            currentScope = currentScope.parent;
3658        }
3659    }
3660
3661    private void findFieldsAndMethodsFromMissingType(
3662            final char[] token,
3663            TypeReference typeRef,
3664            final Scope scope,
3665            final InvocationSite invocationSite,
3666            final Scope invocationScope) {
3667        MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
3668        MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
3669            new MissingTypesGuesser.GuessedTypeRequestor() {
3670                public void accept(
3671                        TypeBinding guessedType,
3672                        Binding[] missingElements,
3673                        int[] missingElementsStarts,
3674                        int[] missingElementsEnds,
3675                        boolean hasProblems) {
3676                    findFieldsAndMethods(
3677                        CompletionEngine.this.completionToken,
3678                        guessedType,
3679                        scope,
3680                        invocationSite,
3681                        invocationScope,
3682                        false,
3683                        false,
3684                        missingElements,
3685                        missingElementsStarts,
3686                        missingElementsEnds,
3687                        hasProblems);
3688                    
3689                }
3690            };
3691        missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
3692    }
3693    
3694    private void findFieldsFromFavorites(
3695            char[] fieldName,
3696            FieldBinding[] fields,
3697            Scope scope,
3698            ObjectVector fieldsFound,
3699            ObjectVector localsFound,
3700            ReferenceBinding receiverType,
3701            InvocationSite invocationSite,
3702            Scope invocationScope) {
3703        
3704        char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.');
3705
3706        int fieldLength = fieldName.length;
3707        next : for (int f = fields.length; --f >= 0;) {
3708            FieldBinding field = fields[f];
3709
3710            if (field.isSynthetic()) continue next;
3711            
3712            // only static fields must be proposed
3713
if (!field.isStatic()) continue next;
3714
3715            if (fieldLength > field.name.length) continue next;
3716
3717            if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)
3718                    && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name))) continue next;
3719
3720            if (this.options.checkDeprecation &&
3721                    field.isViewedAsDeprecated() &&
3722                    !scope.isDefinedInSameUnit(field.declaringClass))
3723                continue next;
3724            
3725            if (this.options.checkVisibility
3726                && !field.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
3727            
3728            for (int i = fieldsFound.size; --i >= 0;) {
3729                Object JavaDoc[] other = (Object JavaDoc[])fieldsFound.elementAt(i);
3730                FieldBinding otherField = (FieldBinding) other[0];
3731                
3732                if (field == otherField) continue next;
3733            }
3734            
3735            fieldsFound.add(new Object JavaDoc[]{field, receiverType});
3736            
3737            int relevance = computeBaseRelevance();
3738            relevance += computeRelevanceForResolution();
3739            relevance += computeRelevanceForInterestingProposal(field);
3740            if (fieldName != null) relevance += computeRelevanceForCaseMatching(fieldName, field.name);
3741            relevance += computeRelevanceForExpectingType(field.type);
3742            relevance += computeRelevanceForStatic(true, true);
3743            relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
3744            
3745            CompilationUnitDeclaration cu = this.unitScope.referenceContext;
3746            int importStart = cu.types[0].declarationSourceStart;
3747            int importEnd = importStart;
3748            
3749            this.noProposal = false;
3750            
3751            if (this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5 ||
3752                    !this.options.suggestStaticImport) {
3753                if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) {
3754                    char[] completion = CharOperation.concat(receiverType.sourceName, field.name, '.');
3755                    
3756                    CompletionProposal proposal = this.createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
3757                    proposal.setDeclarationSignature(getSignature(field.declaringClass));
3758                    proposal.setSignature(getSignature(field.type));
3759                    proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
3760                    proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
3761                    proposal.setPackageName(field.type.qualifiedPackageName());
3762                    proposal.setTypeName(field.type.qualifiedSourceName());
3763                    proposal.setName(field.name);
3764                    proposal.setCompletion(completion);
3765                    proposal.setFlags(field.modifiers);
3766                    proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3767                    proposal.setRelevance(relevance);
3768                    
3769                    char[] typeImportCompletion = createImportCharArray(typeName, false, false);
3770                    
3771                    CompletionProposal typeImportProposal = this.createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
3772                    typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
3773                    typeImportProposal.completionEngine = this;
3774                    char[] packageName = receiverType.qualifiedPackageName();
3775                    typeImportProposal.setDeclarationSignature(packageName);
3776                    typeImportProposal.setSignature(getSignature(receiverType));
3777                    typeImportProposal.setPackageName(packageName);
3778                    typeImportProposal.setTypeName(receiverType.qualifiedSourceName());
3779                    typeImportProposal.setCompletion(typeImportCompletion);
3780                    typeImportProposal.setFlags(receiverType.modifiers);
3781                    typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
3782                    typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
3783                    typeImportProposal.setRelevance(relevance);
3784                    
3785                    proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
3786                    
3787                    this.requestor.accept(proposal);
3788                    if(DEBUG) {
3789                        this.printDebug(proposal);
3790                    }
3791                }
3792            } else {
3793                if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.FIELD_IMPORT)) {
3794                    char[] completion = field.name;
3795                    
3796                    CompletionProposal proposal = this.createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
3797                    proposal.setDeclarationSignature(getSignature(field.declaringClass));
3798                    proposal.setSignature(getSignature(field.type));
3799                    proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
3800                    proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
3801                    proposal.setPackageName(field.type.qualifiedPackageName());
3802                    proposal.setTypeName(field.type.qualifiedSourceName());
3803                    proposal.setName(field.name);
3804                    proposal.setCompletion(completion);
3805                    proposal.setFlags(field.modifiers);
3806                    proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3807                    proposal.setRelevance(relevance);
3808                    
3809                    char[] fieldImportCompletion = createImportCharArray(CharOperation.concat(typeName, field.name, '.'), true, false);
3810
3811                    CompletionProposal fieldImportProposal = this.createProposal(CompletionProposal.FIELD_IMPORT, this.actualCompletionPosition);
3812                    fieldImportProposal.setDeclarationSignature(getSignature(field.declaringClass));
3813                    fieldImportProposal.setSignature(getSignature(field.type));
3814                    fieldImportProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
3815                    fieldImportProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
3816                    fieldImportProposal.setPackageName(field.type.qualifiedPackageName());
3817                    fieldImportProposal.setTypeName(field.type.qualifiedSourceName());
3818                    fieldImportProposal.setName(field.name);
3819                    fieldImportProposal.setCompletion(fieldImportCompletion);
3820                    fieldImportProposal.setFlags(field.modifiers);
3821                    fieldImportProposal.setAdditionalFlags(CompletionFlags.StaticImport);
3822                    fieldImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
3823                    fieldImportProposal.setRelevance(relevance);
3824                    
3825                    proposal.setRequiredProposals(new CompletionProposal[]{fieldImportProposal});
3826                    
3827                    this.requestor.accept(proposal);
3828                    if(DEBUG) {
3829                        this.printDebug(proposal);
3830                    }
3831                }
3832            }
3833        }
3834    }
3835    
3836    private void findImports(CompletionOnImportReference importReference, boolean findMembers) {
3837        char[][] tokens = importReference.tokens;
3838            
3839        char[] importName = CharOperation.concatWith(tokens, '.');
3840        
3841        if (importName.length == 0)
3842            return;
3843            
3844        char[] lastToken = tokens[tokens.length - 1];
3845        if(lastToken != null && lastToken.length == 0)
3846            importName = CharOperation.concat(importName, new char[]{'.'});
3847
3848        this.resolvingImports = true;
3849        this.resolvingStaticImports = importReference.isStatic();
3850            
3851        this.completionToken = importName;
3852        // want to replace the existing .*;
3853
if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
3854            this.nameEnvironment.findPackages(importName, this);
3855        }
3856        if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
3857            this.nameEnvironment.findTypes(
3858                    importName,
3859                    findMembers,
3860                    this.options.camelCaseMatch,
3861                    IJavaSearchConstants.TYPE,
3862                    this);
3863            acceptTypes(null);
3864        }
3865    }
3866    
3867    private void findImportsOfMemberTypes(char[] typeName, ReferenceBinding ref, boolean onlyStatic) {
3868        ReferenceBinding[] memberTypes = ref.memberTypes();
3869        
3870        int typeLength = typeName.length;
3871        next : for (int m = memberTypes.length; --m >= 0;) {
3872            ReferenceBinding memberType = memberTypes[m];
3873            // if (!wantClasses && memberType.isClass()) continue next;
3874
// if (!wantInterfaces && memberType.isInterface()) continue next;
3875

3876            if (onlyStatic && !memberType.isStatic())
3877                continue next;
3878            
3879            if (typeLength > memberType.sourceName.length)
3880                continue next;
3881
3882            if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false/* ignore case */)
3883                    && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName)))
3884                continue next;
3885
3886            if (this.options.checkDeprecation && memberType.isViewedAsDeprecated()) continue next;
3887            
3888            if (this.options.checkVisibility
3889                && !memberType.canBeSeenBy(this.unitScope.fPackage))
3890                continue next;
3891            
3892            char[] completionName = CharOperation.concat(
3893                    memberType.qualifiedPackageName(),
3894                    memberType.qualifiedSourceName(),
3895                    '.');
3896            
3897            completionName = CharOperation.concat(completionName, SEMICOLON);
3898            
3899            int relevance = computeBaseRelevance();
3900            relevance += computeRelevanceForResolution();
3901            relevance += computeRelevanceForInterestingProposal();
3902            relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
3903            relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
3904
3905            if (memberType.isClass()) {
3906                relevance += computeRelevanceForClass();
3907            } else if(memberType.isEnum()) {
3908                relevance += computeRelevanceForEnum();
3909            } else if (memberType.isInterface()) {
3910                relevance += computeRelevanceForInterface();
3911            }
3912            this.noProposal = false;
3913            if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
3914                createTypeProposal(memberType, memberType.qualifiedSourceName(), IAccessRule.K_ACCESSIBLE, completionName, relevance);
3915            }
3916        }
3917    }
3918    
3919    private void findImportsOfStaticFields(char[] fieldName, ReferenceBinding ref) {
3920        FieldBinding[] fields = ref.fields();
3921        
3922        int fieldLength = fieldName.length;
3923        next : for (int m = fields.length; --m >= 0;) {
3924            FieldBinding field = fields[m];
3925
3926            if (fieldLength > field.name.length)
3927                continue next;
3928            
3929            if (field.isSynthetic())
3930                continue next;
3931
3932            if (!field.isStatic())
3933                continue next;
3934
3935            if (!CharOperation.prefixEquals(fieldName, field.name, false/* ignore case */)
3936                && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))
3937                continue next;
3938
3939            if (this.options.checkDeprecation && field.isViewedAsDeprecated()) continue next;
3940            
3941            if (this.options.checkVisibility
3942                && !field.canBeSeenBy(this.unitScope.fPackage))
3943                continue next;
3944            
3945            char[] completionName = CharOperation.concat(field.name, SEMICOLON);
3946            
3947            int relevance = computeBaseRelevance();
3948            relevance += computeRelevanceForResolution();
3949            relevance += computeRelevanceForInterestingProposal();
3950            relevance += computeRelevanceForCaseMatching(fieldName, field.name);
3951            relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
3952
3953            this.noProposal = false;
3954            if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
3955                CompletionProposal proposal = this.createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
3956                proposal.setDeclarationSignature(getSignature(field.declaringClass));
3957                proposal.setSignature(getSignature(field.type));
3958                proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
3959                proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
3960                proposal.setPackageName(field.type.qualifiedPackageName());
3961                proposal.setTypeName(field.type.qualifiedSourceName());
3962                proposal.setName(field.name);
3963                proposal.setCompletion(completionName);
3964                proposal.setFlags(field.modifiers);
3965                proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3966                proposal.setRelevance(relevance);
3967                this.requestor.accept(proposal);
3968                if(DEBUG) {
3969                    this.printDebug(proposal);
3970                }
3971            }
3972        }
3973    }
3974    
3975    private void findImportsOfStaticMethods(char[] methodName, ReferenceBinding ref) {
3976        MethodBinding[] methods = ref.methods();
3977        
3978        int methodLength = methodName.length;
3979        next : for (int m = methods.length; --m >= 0;) {
3980            MethodBinding method = methods[m];
3981
3982            if (method.isSynthetic()) continue next;
3983
3984            if (method.isDefaultAbstract()) continue next;
3985
3986            if (method.isConstructor()) continue next;
3987
3988            if (!method.isStatic()) continue next;
3989
3990            if (this.options.checkDeprecation && method.isViewedAsDeprecated()) continue next;
3991            
3992            if (this.options.checkVisibility
3993                && !method.canBeSeenBy(this.unitScope.fPackage)) continue next;
3994            
3995            if (methodLength > method.selector.length)
3996                continue next;
3997
3998            if (!CharOperation.prefixEquals(methodName, method.selector, false/* ignore case */)
3999                    && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
4000                continue next;
4001            
4002            int length = method.parameters.length;
4003            char[][] parameterPackageNames = new char[length][];
4004            char[][] parameterTypeNames = new char[length][];
4005
4006            for (int i = 0; i < length; i++) {
4007                TypeBinding type = method.original().parameters[i];
4008                parameterPackageNames[i] = type.qualifiedPackageName();
4009                parameterTypeNames[i] = type.qualifiedSourceName();
4010            }
4011            char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
4012
4013            
4014            char[] completionName = CharOperation.concat(
4015                    method.declaringClass.qualifiedPackageName(),
4016                    '.',
4017                    method.declaringClass.qualifiedSourceName(),
4018                    '.',
4019                    method.selector);
4020            
4021            completionName = CharOperation.concat(completionName, SEMICOLON);
4022            
4023            int relevance = computeBaseRelevance();
4024            relevance += computeRelevanceForResolution();
4025            relevance += computeRelevanceForInterestingProposal();
4026            relevance += computeRelevanceForCaseMatching(methodName, method.selector);
4027            relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4028
4029            this.noProposal = false;
4030            if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
4031                CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_NAME_REFERENCE, this.actualCompletionPosition);
4032                proposal.setDeclarationSignature(getSignature(method.declaringClass));
4033                proposal.setSignature(getSignature(method));
4034                proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
4035                proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
4036                proposal.setParameterPackageNames(parameterPackageNames);
4037                proposal.setParameterTypeNames(parameterTypeNames);
4038                proposal.setPackageName(method.returnType.qualifiedPackageName());
4039                proposal.setTypeName(method.returnType.qualifiedSourceName());
4040                proposal.setName(method.selector);
4041                proposal.setCompletion(completionName);
4042                proposal.setFlags(method.modifiers);
4043                proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4044                proposal.setRelevance(relevance);
4045                if(parameterNames != null) proposal.setParameterNames(parameterNames);
4046                this.requestor.accept(proposal);
4047                if(DEBUG) {
4048                    this.printDebug(proposal);
4049                }
4050            }
4051        }
4052    }
4053
4054    /*
4055     * Find javadoc block tags for a given completion javadoc tag node
4056     */

4057    private void findJavadocBlockTags(CompletionOnJavadocTag javadocTag) {
4058        char[][] possibleTags = javadocTag.getPossibleBlockTags();
4059        if (possibleTags == null) return;
4060        int length = possibleTags.length;
4061        for (int i=0; i<length; i++) {
4062            int relevance = computeBaseRelevance();
4063            relevance += computeRelevanceForInterestingProposal();
4064            relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
4065

4066            this.noProposal = false;
4067            if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_BLOCK_TAG)) {
4068                char[] possibleTag = possibleTags[i];
4069                CompletionProposal proposal = this.createProposal(CompletionProposal.JAVADOC_BLOCK_TAG, this.actualCompletionPosition);
4070                proposal.setName(possibleTag);
4071                int tagLength = possibleTag.length;
4072                char[] completion = new char[1+tagLength];
4073                completion[0] = '@';
4074                System.arraycopy(possibleTag, 0, completion, 1, tagLength);
4075                proposal.setCompletion(completion);
4076                proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4077                proposal.setRelevance(relevance);
4078                this.requestor.accept(proposal);
4079                if (DEBUG) {
4080                    this.printDebug(proposal);
4081                }
4082            }
4083        }
4084    }
4085
4086    /*
4087     * Find javadoc inline tags for a given completion javadoc tag node
4088     */

4089    private void findJavadocInlineTags(CompletionOnJavadocTag javadocTag) {
4090        char[][] possibleTags = javadocTag.getPossibleInlineTags();
4091        if (possibleTags == null) return;
4092        int length = possibleTags.length;
4093        for (int i=0; i<length; i++) {
4094            int relevance = computeBaseRelevance();
4095            relevance += computeRelevanceForInterestingProposal();
4096            relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
4097

4098            this.noProposal = false;
4099            if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_INLINE_TAG)) {
4100                char[] possibleTag = possibleTags[i];
4101                CompletionProposal proposal = this.createProposal(CompletionProposal.JAVADOC_INLINE_TAG, this.actualCompletionPosition);
4102                proposal.setName(possibleTag);
4103                int tagLength = possibleTag.length;
4104// boolean inlineTagStarted = javadocTag.completeInlineTagStarted();
4105
char[] completion = new char[2+tagLength+1];
4106                completion[0] = '{';
4107                completion[1] = '@';
4108                System.arraycopy(possibleTag, 0, completion, 2, tagLength);
4109                // do not add space at end of inline tag (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=121026)
4110
//completion[tagLength+2] = ' ';
4111
completion[tagLength+2] = '}';
4112                proposal.setCompletion(completion);
4113                proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4114                proposal.setRelevance(relevance);
4115                this.requestor.accept(proposal);
4116                if (DEBUG) {
4117                    this.printDebug(proposal);
4118                }
4119            }
4120        }
4121    }
4122
4123    // what about onDemand types? Ignore them since it does not happen!
4124
// import p1.p2.A.*;
4125
private void findKeywords(char[] keyword, char[][] choices, boolean canCompleteEmptyToken, boolean staticFieldsAndMethodOnly) {
4126        if(choices == null || choices.length == 0) return;
4127        
4128        int length = keyword.length;
4129        if (canCompleteEmptyToken || length > 0)
4130            for (int i = 0; i < choices.length; i++)
4131                if (length <= choices[i].length
4132                    && CharOperation.prefixEquals(keyword, choices[i], false /* ignore case */
4133                )){
4134                    int relevance = computeBaseRelevance();
4135                    relevance += computeRelevanceForResolution();
4136                    relevance += computeRelevanceForInterestingProposal();
4137                    relevance += computeRelevanceForCaseMatching(keyword, choices[i]);
4138                    relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
4139
if (staticFieldsAndMethodOnly && this.insideQualifiedReference) relevance += R_NON_INHERITED;
4140                    
4141                    if(CharOperation.equals(choices[i], Keywords.TRUE) || CharOperation.equals(choices[i], Keywords.FALSE)) {
4142                        relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
4143                        relevance += computeRelevanceForQualification(false);
4144                    }
4145                    this.noProposal = false;
4146                    if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
4147                        CompletionProposal proposal = this.createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
4148                        proposal.setName(choices[i]);
4149                        proposal.setCompletion(choices[i]);
4150                        proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4151                        proposal.setRelevance(relevance);
4152                        this.requestor.accept(proposal);
4153                        if(DEBUG) {
4154                            this.printDebug(proposal);
4155                        }
4156                    }
4157                }
4158    }
4159    private void findTrueOrFalseKeywords(char[][] choices) {
4160        if(choices == null || choices.length == 0) return;
4161        
4162        if(this.expectedTypesPtr != 0 || this.expectedTypes[0] != TypeBinding.BOOLEAN) return;
4163        
4164        for (int i = 0; i < choices.length; i++) {
4165            if (CharOperation.equals(choices[i], Keywords.TRUE) ||
4166                    CharOperation.equals(choices[i], Keywords.FALSE)
4167            ){
4168                int relevance = computeBaseRelevance();
4169                relevance += computeRelevanceForResolution();
4170                relevance += computeRelevanceForInterestingProposal();
4171                relevance += computeRelevanceForCaseMatching(CharOperation.NO_CHAR, choices[i]);
4172                relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
4173
relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
4174                relevance += computeRelevanceForQualification(false);
4175                relevance += R_TRUE_OR_FALSE;
4176
4177                this.noProposal = false;
4178                if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
4179                    CompletionProposal proposal = this.createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
4180                    proposal.setName(choices[i]);
4181                    proposal.setCompletion(choices[i]);
4182                    proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4183                    proposal.setRelevance(relevance);
4184                    this.requestor.accept(proposal);
4185                    if(DEBUG) {
4186                        this.printDebug(proposal);
4187                    }
4188                }
4189            }
4190        }
4191    }
4192    
4193    private void findKeywordsForMember(char[] token, int modifiers) {
4194        char[][] keywords = new char[Keywords.COUNT][];
4195        int count = 0;
4196                
4197        // visibility
4198
if((modifiers & ClassFileConstants.AccPrivate) == 0
4199            && (modifiers & ClassFileConstants.AccProtected) == 0
4200            && (modifiers & ClassFileConstants.AccPublic) == 0) {
4201            keywords[count++] = Keywords.PROTECTED;
4202            keywords[count++] = Keywords.PUBLIC;
4203            if((modifiers & ClassFileConstants.AccAbstract) == 0) {
4204                keywords[count++] = Keywords.PRIVATE;
4205            }
4206        }
4207        
4208        if((modifiers & ClassFileConstants.AccAbstract) == 0) {
4209            // abtract
4210
if((modifiers & ~(ExtraCompilerModifiers.AccVisibilityMASK | ClassFileConstants.AccStatic)) == 0) {
4211                keywords[count++] = Keywords.ABSTRACT;
4212            }
4213            
4214            // final
4215
if((modifiers & ClassFileConstants.AccFinal) == 0) {
4216                keywords[count++] = Keywords.FINAL;
4217            }
4218            
4219            // static
4220
if((modifiers & ClassFileConstants.AccStatic) == 0) {
4221                keywords[count++] = Keywords.STATIC;
4222            }
4223            
4224            boolean canBeField = true;
4225            boolean canBeMethod = true;
4226            boolean canBeType = true;
4227            if((modifiers & ClassFileConstants.AccNative) != 0
4228                || (modifiers & ClassFileConstants.AccStrictfp) != 0
4229                || (modifiers & ClassFileConstants.AccSynchronized) != 0) {
4230                canBeField = false;
4231                canBeType = false;
4232            }
4233            
4234            if((modifiers & ClassFileConstants.AccTransient) != 0
4235                || (modifiers & ClassFileConstants.AccVolatile) != 0) {
4236                canBeMethod = false;
4237                canBeType = false;
4238            }
4239            
4240            if(canBeField) {
4241                // transient
4242
if((modifiers & ClassFileConstants.AccTransient) == 0) {
4243                    keywords[count++] = Keywords.TRANSIENT;
4244                }
4245                
4246                // volatile
4247
if((modifiers & ClassFileConstants.AccVolatile) == 0) {
4248                    keywords[count++] = Keywords.VOLATILE;
4249                }
4250            }
4251            
4252            if(canBeMethod) {
4253                // native
4254
if((modifiers & ClassFileConstants.AccNative) == 0) {
4255                    keywords[count++] = Keywords.NATIVE;
4256                }
4257    
4258                // strictfp
4259
if((modifiers & ClassFileConstants.AccStrictfp) == 0) {
4260                    keywords[count++] = Keywords.STRICTFP;
4261                }
4262                
4263                // synchronized
4264
if((modifiers & ClassFileConstants.AccSynchronized) == 0) {
4265                    keywords[count++] = Keywords.SYNCHRONIZED;
4266                }
4267            }
4268            
4269            if(canBeType) {
4270                keywords[count++] = Keywords.CLASS;
4271                keywords[count++] = Keywords.INTERFACE;
4272            }
4273        } else {
4274            // class
4275
keywords[count++] = Keywords.CLASS;
4276            keywords[count++] = Keywords.INTERFACE;
4277        }
4278        System.arraycopy(keywords, 0, keywords = new char[count][], 0, count);
4279        
4280        findKeywords(token, keywords, false, false);
4281    }
4282
4283    // Helper method for findMemberTypes(char[], ReferenceBinding, Scope)
4284
private void findMemberTypes(
4285        char[] typeName,
4286        ReferenceBinding[] memberTypes,
4287        ObjectVector typesFound,
4288        ReferenceBinding receiverType,
4289        SourceTypeBinding invocationType,
4290        boolean staticOnly,
4291        boolean staticFieldsAndMethodOnly,
4292        boolean fromStaticImport,
4293        boolean checkQualification,
4294        Scope scope) {
4295
4296        // Inherited member types which are hidden by subclasses are filtered out
4297
// No visibility checks can be performed without the scope & invocationSite
4298
int typeLength = typeName.length;
4299        next : for (int m = memberTypes.length; --m >= 0;) {
4300            ReferenceBinding memberType = memberTypes[m];
4301            // if (!wantClasses && memberType.isClass()) continue next;
4302
// if (!wantInterfaces && memberType.isInterface()) continue next;
4303

4304            if (staticOnly && !memberType.isStatic()) continue next;
4305            
4306            if (isForbidden(memberType)) continue next;
4307            
4308            if (typeLength > memberType.sourceName.length)
4309                continue next;
4310
4311            if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false/* ignore case */)
4312                    && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName)))
4313                continue next;
4314
4315            if (this.options.checkDeprecation &&
4316                    memberType.isViewedAsDeprecated() &&
4317                    !scope.isDefinedInSameUnit(memberType))
4318                continue next;
4319            
4320            if (this.options.checkVisibility) {
4321                if (invocationType != null && !memberType.canBeSeenBy(receiverType, invocationType)) {
4322                    continue next;
4323                } else if(invocationType == null && !memberType.canBeSeenBy(this.unitScope.fPackage)) {
4324                    continue next;
4325                }
4326            }
4327
4328            for (int i = typesFound.size; --i >= 0;) {
4329                ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(i);
4330
4331                if (memberType == otherType)
4332                    continue next;
4333
4334                if (CharOperation.equals(memberType.sourceName, otherType.sourceName, true)) {
4335
4336                    if (memberType.enclosingType().isSuperclassOf(otherType.enclosingType()))
4337                        continue next;
4338
4339                    if (otherType.enclosingType().isInterface())
4340                        if (memberType.enclosingType()
4341                            .implementsInterface(otherType.enclosingType(), true))
4342                            continue next;
4343
4344                    if (memberType.enclosingType().isInterface())
4345                        if (otherType.enclosingType()
4346                            .implementsInterface(memberType.enclosingType(), true))
4347                            continue next;
4348                }
4349            }
4350
4351            typesFound.add(memberType);
4352
4353            if(!this.insideQualifiedReference) {
4354                if(this.assistNodeIsClass) {
4355                    if(!memberType.isClass()) continue next;
4356                } else if(this.assistNodeIsInterface) {
4357                    if(!memberType.isInterface() && !memberType.isAnnotationType()) continue next;
4358                } else if (this.assistNodeIsAnnotation) {
4359                    if(!memberType.isAnnotationType()) continue next;
4360                }
4361            }
4362            
4363            char[] completionName = memberType.sourceName();
4364            
4365            boolean isQualified = false;
4366            if(checkQualification && !fromStaticImport) {
4367                char[] memberPackageName = memberType.qualifiedPackageName();
4368                char[] memberTypeName = memberType.sourceName();
4369                char[] memberEnclosingTypeNames = memberType.enclosingType().qualifiedSourceName();
4370                if (mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, memberType.modifiers)) {
4371                    if (memberPackageName == null || memberPackageName.length == 0)
4372                        if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
4373                            break next; // ignore types from the default package from outside it
4374
isQualified = true;
4375                    completionName =
4376                        CharOperation.concat(
4377                                memberPackageName,
4378                                CharOperation.concat(
4379                                        memberEnclosingTypeNames,
4380                                        memberTypeName,
4381                                        '.'),
4382                                '.');
4383                }
4384            }
4385            
4386            int relevance = computeBaseRelevance();
4387            relevance += computeRelevanceForResolution();
4388            relevance += computeRelevanceForInterestingProposal();
4389            relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
4390            relevance += computeRelevanceForExpectingType(memberType);
4391            relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4392            if(!insideQualifiedReference) {
4393                relevance += computeRelevanceForQualification(isQualified);
4394            }
4395            if (staticFieldsAndMethodOnly && this.insideQualifiedReference) relevance += R_NON_INHERITED; // This criterion doesn't concern types and is added to be balanced with field and method relevance.
4396

4397            if (memberType.isAnnotationType()) {
4398                relevance += computeRelevanceForAnnotation();
4399                relevance += computeRelevanceForAnnotationTarget(memberType);
4400            } else if (memberType.isClass()) {
4401                relevance += computeRelevanceForClass();
4402                relevance += computeRelevanceForException(memberType.sourceName);
4403            } else if(memberType.isEnum()) {
4404                relevance += computeRelevanceForEnum();
4405            } else if(memberType.isInterface()) {
4406                relevance += computeRelevanceForInterface();
4407            }
4408                
4409            this.noProposal = false;
4410            createTypeProposal(memberType, memberType.qualifiedSourceName(), IAccessRule.K_ACCESSIBLE, completionName, relevance);
4411        }
4412    }
4413
4414    private void findMemberTypes(
4415        char[] typeName,
4416        ReferenceBinding receiverType,
4417        Scope scope,
4418        SourceTypeBinding typeInvocation,
4419        boolean staticOnly,
4420        boolean staticFieldsAndMethodOnly,
4421        ObjectVector typesFound) {
4422        findMemberTypes(
4423                typeName,
4424                receiverType,
4425                scope,
4426                typeInvocation,
4427                staticOnly,
4428                staticFieldsAndMethodOnly,
4429                false,
4430                false,
4431                false,
4432                null,
4433                typesFound);
4434    }
4435    private void findMemberTypes(
4436        char[] typeName,
4437        ReferenceBinding receiverType,
4438        Scope scope,
4439        SourceTypeBinding typeInvocation,
4440        boolean staticOnly,
4441        boolean staticFieldsAndMethodOnly,
4442        boolean fromStaticImport,
4443        boolean checkQualification,
4444        boolean proposeAllMemberTypes,
4445        SourceTypeBinding typeToIgnore,
4446        ObjectVector typesFound) {
4447
4448        ReferenceBinding currentType = receiverType;
4449        if (typeName == null)
4450            return;
4451
4452        if (this.assistNodeIsSuperType && !this.insideQualifiedReference) return; // we're trying to find a supertype
4453

4454        if (currentType.superInterfaces() == null) return;
4455        
4456        if (this.insideQualifiedReference
4457            || typeName.length == 0) { // do not search up the hierarchy
4458

4459            findMemberTypes(
4460                typeName,
4461                currentType.memberTypes(),
4462                typesFound,
4463                receiverType,
4464                typeInvocation,
4465                staticOnly,
4466                staticFieldsAndMethodOnly,
4467                fromStaticImport,
4468                checkQualification,
4469                scope);
4470            return;
4471        }
4472
4473        ReferenceBinding[] interfacesToVisit = null;
4474        int nextPosition = 0;
4475
4476        do {
4477            ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
4478            if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
4479                if (interfacesToVisit == null) {
4480                    interfacesToVisit = itsInterfaces;
4481                    nextPosition = interfacesToVisit.length;
4482                } else {
4483                    int itsLength = itsInterfaces.length;
4484                    if (nextPosition + itsLength >= interfacesToVisit.length)
4485                        System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
4486                    nextInterface : for (int a = 0; a < itsLength; a++) {
4487                        ReferenceBinding next = itsInterfaces[a];
4488                        for (int b = 0; b < nextPosition; b++)
4489                            if (next == interfacesToVisit[b]) continue nextInterface;
4490                        interfacesToVisit[nextPosition++] = next;
4491                    }
4492                }
4493            }
4494            
4495            findMemberTypes(
4496                typeName,
4497                currentType.memberTypes(),
4498                typesFound,
4499                receiverType,
4500                typeInvocation,
4501                staticOnly,
4502                staticFieldsAndMethodOnly,
4503                fromStaticImport,
4504                checkQualification,
4505                scope);
4506            
4507            currentType = currentType.superclass();
4508        } while (currentType != null);
4509
4510        if(proposeAllMemberTypes) {
4511            ReferenceBinding[] memberTypes = receiverType.memberTypes();
4512            for (int i = 0; i < memberTypes.length; i++) {
4513                if(memberTypes[i] != typeToIgnore) {
4514                    findSubMemberTypes(
4515                        typeName,
4516                        memberTypes[i],
4517                        scope,
4518                        typeInvocation,
4519                        staticOnly,
4520                        staticFieldsAndMethodOnly,
4521                        fromStaticImport,
4522                        typesFound);
4523                }
4524            }
4525        }
4526
4527        if (interfacesToVisit != null) {
4528            for (int i = 0; i < nextPosition; i++) {
4529                ReferenceBinding anInterface = interfacesToVisit[i];
4530                findMemberTypes(
4531                    typeName,
4532                    anInterface.memberTypes(),
4533                    typesFound,
4534                    receiverType,
4535                    typeInvocation,
4536                    staticOnly,
4537                    staticFieldsAndMethodOnly,
4538                    fromStaticImport,
4539                    checkQualification,
4540                    scope);
4541                        
4542                ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
4543                if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
4544                    int itsLength = itsInterfaces.length;
4545                    if (nextPosition + itsLength >= interfacesToVisit.length)
4546                        System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
4547                    nextInterface : for (int a = 0; a < itsLength; a++) {
4548                        ReferenceBinding next = itsInterfaces[a];
4549                        for (int b = 0; b < nextPosition; b++)
4550                            if (next == interfacesToVisit[b]) continue nextInterface;
4551                        interfacesToVisit[nextPosition++] = next;
4552                    }
4553                }
4554            }
4555        }
4556    }
4557
4558    /*
4559     * Find javadoc parameter names.
4560     */

4561    private void findJavadocParamNames(char[] token, char[][] missingParams, boolean isTypeParam) {
4562
4563        if (missingParams == null) return;
4564
4565        // Get relevance
4566
int relevance = computeBaseRelevance();
4567        relevance += computeRelevanceForInterestingProposal();
4568        relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for param name
4569
if (!isTypeParam) relevance += R_INTERESTING;
4570
4571        // Propose missing param
4572
int length = missingParams.length;
4573        relevance += length;
4574        for (int i=0; i<length; i++) {
4575            char[] argName = missingParams[i];
4576            if (token == null || CharOperation.prefixEquals(token, argName)) {
4577                
4578                this.noProposal = false;
4579                if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
4580                    CompletionProposal proposal = this.createProposal(CompletionProposal.JAVADOC_PARAM_REF, this.actualCompletionPosition);
4581                    proposal.setName(argName);
4582                    char[] completion = isTypeParam ? CharOperation.concat('<', argName, '>') : argName;
4583                    proposal.setCompletion(completion);
4584                    proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4585                    proposal.setRelevance(--relevance);
4586                    this.requestor.accept(proposal);
4587                    if (DEBUG) {
4588                        this.printDebug(proposal);
4589                    }
4590                }
4591            }
4592        }
4593    }
4594
4595    private void findSubMemberTypes(
4596        char[] typeName,
4597        ReferenceBinding receiverType,
4598        Scope scope,
4599        SourceTypeBinding typeInvocation,
4600        boolean staticOnly,
4601        boolean staticFieldsAndMethodOnly,
4602        boolean fromStaticImport,
4603        ObjectVector typesFound) {
4604
4605        ReferenceBinding currentType = receiverType;
4606        if (typeName == null || typeName.length == 0)
4607            return;
4608
4609        if (this.assistNodeIsSuperType && !this.insideQualifiedReference) return; // we're trying to find a supertype
4610

4611        if (currentType.superInterfaces() == null) return;
4612         
4613        findMemberTypes(
4614                typeName,
4615                currentType.memberTypes(),
4616                typesFound,
4617                receiverType,
4618                typeInvocation,
4619                staticOnly,
4620                staticFieldsAndMethodOnly,
4621                fromStaticImport,
4622                true,
4623                scope);
4624        
4625        ReferenceBinding[] memberTypes = receiverType.memberTypes();
4626        next : for (int i = 0; i < memberTypes.length; i++) {
4627            if (this.options.checkVisibility) {
4628                if (typeInvocation != null && !memberTypes[i].canBeSeenBy(receiverType, typeInvocation)) {
4629                    continue next;
4630                } else if(typeInvocation == null && !memberTypes[i].canBeSeenBy(this.unitScope.fPackage)) {
4631                    continue next;
4632                }
4633            }
4634            findSubMemberTypes(
4635                typeName,
4636                memberTypes[i],
4637                scope,
4638                typeInvocation,
4639                staticOnly,
4640                staticFieldsAndMethodOnly,
4641                fromStaticImport,
4642                typesFound);
4643        }
4644    }
4645
4646    private void findInterfacesMethods(
4647        char[] selector,
4648        TypeBinding[] typeArgTypes,
4649        TypeBinding[] argTypes,
4650        ReferenceBinding receiverType,
4651        ReferenceBinding[] itsInterfaces,
4652        Scope scope,
4653        ObjectVector methodsFound,
4654        boolean onlyStaticMethods,
4655        boolean exactMatch,
4656        boolean isCompletingDeclaration,
4657        InvocationSite invocationSite,
4658        Scope invocationScope,
4659        boolean implicitCall,
4660        boolean superCall,
4661        boolean canBePrefixed,
4662        Binding[] missingElements,
4663        int[] missingElementssStarts,
4664        int[] missingElementsEnds,
4665        boolean missingElementsHaveProblems) {
4666
4667        if (selector == null)
4668            return;
4669
4670        if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
4671            ReferenceBinding[] interfacesToVisit = itsInterfaces;
4672            int nextPosition = interfacesToVisit.length;
4673
4674            for (int i = 0; i < nextPosition; i++) {
4675                ReferenceBinding currentType = interfacesToVisit[i];
4676                MethodBinding[] methods = currentType.availableMethods();
4677                if(methods != null) {
4678                    if(isCompletingDeclaration) {
4679                        findLocalMethodDeclarations(
4680                            selector,
4681                            methods,
4682                            scope,
4683                            methodsFound,
4684                            exactMatch,
4685                            receiverType);
4686                    } else {
4687                        findLocalMethods(
4688                            selector,
4689                            typeArgTypes,
4690                            argTypes,
4691                            methods,
4692                            scope,
4693                            methodsFound,
4694                            onlyStaticMethods,
4695                            exactMatch,
4696                            receiverType,
4697                            invocationSite,
4698                            invocationScope,
4699                            implicitCall,
4700                            superCall,
4701                            canBePrefixed,
4702                            missingElements,
4703                            missingElementssStarts,
4704                            missingElementsEnds,
4705                            missingElementsHaveProblems);
4706                    }
4707                }
4708
4709                if ((itsInterfaces = currentType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
4710                    int itsLength = itsInterfaces.length;
4711                    if (nextPosition + itsLength >= interfacesToVisit.length)
4712                        System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
4713                    nextInterface : for (int a = 0; a < itsLength; a++) {
4714                        ReferenceBinding next = itsInterfaces[a];
4715                        for (int b = 0; b < nextPosition; b++)
4716                            if (next == interfacesToVisit[b]) continue nextInterface;
4717                        interfacesToVisit[nextPosition++] = next;
4718                    }
4719                }
4720            }
4721        }
4722    }
4723    
4724    private void findImplicitMessageSends(
4725        char[] token,
4726        TypeBinding[] argTypes,
4727        Scope scope,
4728        InvocationSite invocationSite,
4729        Scope invocationScope) {
4730
4731        if (token == null)
4732            return;
4733
4734        boolean staticsOnly = false;
4735        // need to know if we're in a static context (or inside a constructor)
4736
ObjectVector methodsFound = new ObjectVector();
4737
4738        done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
4739

4740            switch (scope.kind) {
4741
4742                case Scope.METHOD_SCOPE :
4743                    // handle the error case inside an explicit constructor call (see MethodScope>>findField)
4744
MethodScope methodScope = (MethodScope) scope;
4745                    staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
4746                    break;
4747
4748                case Scope.CLASS_SCOPE :
4749                    ClassScope classScope = (ClassScope) scope;
4750                    SourceTypeBinding enclosingType = classScope.referenceContext.binding;
4751                    findMethods(
4752                        token,
4753                        null,
4754                        argTypes,
4755                        enclosingType,
4756                        classScope,
4757                        methodsFound,
4758                        staticsOnly,
4759                        true,
4760                        false,
4761                        invocationSite,
4762                        invocationScope,
4763                        true,
4764                        false,
4765                        true,
4766                        null,
4767                        null,
4768                        null,
4769                        false);
4770                    staticsOnly |= enclosingType.isStatic();
4771                    break;
4772
4773                case Scope.COMPILATION_UNIT_SCOPE :
4774                    break done;
4775            }
4776            scope = scope.parent;
4777        }
4778    }
4779
4780    // Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
4781
private void findLocalMethods(
4782        char[] methodName,
4783        TypeBinding[] typeArgTypes,
4784        TypeBinding[] argTypes,
4785        MethodBinding[] methods,
4786        Scope scope,
4787        ObjectVector methodsFound,
4788        boolean onlyStaticMethods,
4789        boolean exactMatch,
4790        ReferenceBinding receiverType,
4791        InvocationSite invocationSite,
4792        Scope invocationScope,
4793        boolean implicitCall,
4794        boolean superCall,
4795        boolean canBePrefixed,
4796        Binding[] missingElements,
4797        int[] missingElementsStarts,
4798        int[] missingElementsEnds,
4799        boolean missingElementsHaveProblems) {
4800
4801        ObjectVector newMethodsFound = new ObjectVector();
4802        // Inherited methods which are hidden by subclasses are filtered out
4803
// No visibility checks can be performed without the scope & invocationSite
4804

4805        int methodLength = methodName.length;
4806        int minTypeArgLength = typeArgTypes == null ? 0 : typeArgTypes.length;
4807        int minArgLength = argTypes == null ? 0 : argTypes.length;
4808
4809        next : for (int f = methods.length; --f >= 0;) {
4810            MethodBinding method = methods[f];
4811
4812            if (method.isSynthetic()) continue next;
4813
4814            if (method.isDefaultAbstract()) continue next;
4815
4816            if (method.isConstructor()) continue next;
4817            
4818            if (this.options.checkDeprecation &&
4819                    method.isViewedAsDeprecated() &&
4820                    !scope.isDefinedInSameUnit(method.declaringClass))
4821                continue next;
4822
4823            //TODO (david) perhaps the relevance of a void method must be lesser than other methods
4824
//if (expectedTypesPtr > -1 && method.returnType == BaseTypes.VoidBinding) continue next;
4825

4826            if (onlyStaticMethods && !method.isStatic()) continue next;
4827
4828            if (this.options.checkVisibility
4829                && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
4830
4831            if(superCall && method.isAbstract()) {
4832                methodsFound.add(new Object JavaDoc[]{method, receiverType});
4833                continue next;
4834            }
4835
4836            if (exactMatch) {
4837                if (!CharOperation.equals(methodName, method.selector, false /* ignore case */)) {
4838                    continue next;
4839                }
4840            } else {
4841                if (methodLength > method.selector.length) continue next;
4842                if (!CharOperation.prefixEquals(methodName, method.selector, false /* ignore case */)
4843                        && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) {
4844                    continue next;
4845                }
4846            }
4847            
4848            if (minTypeArgLength != 0 && minTypeArgLength != method.typeVariables.length)
4849                continue next;
4850            
4851            if (minTypeArgLength != 0) {
4852                method = scope.environment().createParameterizedGenericMethod(method, typeArgTypes);
4853            }
4854            
4855            if (minArgLength > method.parameters.length)
4856                continue next;
4857
4858            for (int a = minArgLength; --a >= 0;){
4859                if (argTypes[a] != null) { // can be null if it could not be resolved properly
4860
if (!argTypes[a].isCompatibleWith(method.parameters[a])) {
4861                        continue next;
4862                    }
4863                }
4864            }
4865            
4866            boolean prefixRequired = false;
4867            
4868            for (int i = methodsFound.size; --i >= 0;) {
4869                Object JavaDoc[] other = (Object JavaDoc[]) methodsFound.elementAt(i);
4870                MethodBinding otherMethod = (MethodBinding) other[0];
4871                ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
4872                if (method == otherMethod && receiverType == otherReceiverType)
4873                    continue next;
4874                
4875                if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
4876                    if (receiverType == otherReceiverType) {
4877                        if (lookupEnvironment.methodVerifier().doesMethodOverride(otherMethod, method)) {
4878                            if (!superCall || !otherMethod.declaringClass.isInterface()) {
4879                                continue next;
4880                            }
4881                        }
4882                    } else {
4883                        if (lookupEnvironment.methodVerifier().doesMethodOverride(otherMethod, method)) {
4884                            if(receiverType.isAnonymousType()) continue next;
4885                            
4886                            if(!superCall) {
4887                                if(!canBePrefixed) continue next;
4888                                
4889                                prefixRequired = true;
4890                            }
4891                        }
4892                    }
4893                }
4894            }
4895
4896            newMethodsFound.add(new Object JavaDoc[]{method, receiverType});
4897            
4898            ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeWithSameErasure(method.declaringClass);
4899            if (method.declaringClass != superTypeWithSameErasure) {
4900                MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
4901                for (int i = 0; i < otherMethods.length; i++) {
4902                    if(otherMethods[i].original() == method.original()) {
4903                        method = otherMethods[i];
4904                    }
4905                }
4906            }
4907            
4908            int length = method.parameters.length;
4909            char[][] parameterPackageNames = new char[length][];
4910            char[][] parameterTypeNames = new char[length][];
4911
4912            for (int i = 0; i < length; i++) {
4913                TypeBinding type = method.original().parameters[i];
4914                parameterPackageNames[i] = type.qualifiedPackageName();
4915                parameterTypeNames[i] = type.qualifiedSourceName();
4916            }
4917            char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
4918
4919            char[] completion = CharOperation.NO_CHAR;
4920            
4921            int previousStartPosition = this.startPosition;
4922
4923            // Special case for completion in javadoc
4924
if (this.assistNodeInJavadoc > 0) {
4925                Expression receiver = null;
4926                if (invocationSite instanceof CompletionOnJavadocMessageSend) {
4927                    CompletionOnJavadocMessageSend msg = (CompletionOnJavadocMessageSend) invocationSite;
4928                    receiver = msg.receiver;
4929                } else if (invocationSite instanceof CompletionOnJavadocFieldReference) {
4930                    CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
4931                    receiver = fieldRef.receiver;
4932                }
4933                if (receiver != null) {
4934                    StringBuffer JavaDoc javadocCompletion = new StringBuffer JavaDoc();
4935                    if (receiver.isThis()) {
4936                        if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
4937                            javadocCompletion.append('#');
4938                        }
4939                    } else if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
4940                        if (receiver instanceof JavadocSingleTypeReference) {
4941                            JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver;
4942                            javadocCompletion.append(typeRef.token);
4943                            javadocCompletion.append('#');
4944                        } else if (receiver instanceof JavadocQualifiedTypeReference) {
4945                            JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver;
4946                            completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), method.selector, '#');
4947                            for (int t=0,nt =typeRef.tokens.length; t<nt; t++) {
4948                                if (t>0) javadocCompletion.append('.');
4949                                javadocCompletion.append(typeRef.tokens[t]);
4950                            }
4951                            javadocCompletion.append('#');
4952                        }
4953                    }
4954                    javadocCompletion.append(method.selector);
4955                    // Append parameters types
4956
javadocCompletion.append('(');
4957                    if (method.parameters != null) {
4958                        boolean isVarargs = method.isVarargs();
4959                        for (int p=0, ln=method.parameters.length; p<ln; p++) {
4960                            if (p>0) javadocCompletion.append(", "); //$NON-NLS-1$
4961
TypeBinding argTypeBinding = method.parameters[p];
4962                            if (isVarargs && p == ln - 1) {
4963                                createVargsType(argTypeBinding.erasure(), javadocCompletion);
4964                            } else {
4965                                createType(argTypeBinding.erasure(), javadocCompletion);
4966                            }
4967                        }
4968                    }
4969                    javadocCompletion.append(')');
4970                    completion = javadocCompletion.toString().toCharArray();
4971                }
4972            } else {
4973                // nothing to insert - do not want to replace the existing selector & arguments
4974
if (!exactMatch) {
4975                    if (this.source != null
4976                        && this.source.length > this.endPosition
4977                        && this.source[this.endPosition] == '(')
4978                        completion = method.selector;
4979                    else
4980                        completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
4981                } else {
4982                    if(prefixRequired && (this.source != null)) {
4983                        completion = CharOperation.subarray(this.source, this.startPosition, this.endPosition);
4984                    } else {
4985                        this.startPosition = this.endPosition;
4986                    }
4987                }
4988                
4989                if(prefixRequired || this.options.forceImplicitQualification){
4990                    char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), method.isStatic());
4991                    completion = CharOperation.concat(prefix,completion,'.');
4992                }
4993            }
4994
4995            int relevance = computeBaseRelevance();
4996            relevance += computeRelevanceForResolution();
4997            relevance += computeRelevanceForInterestingProposal();
4998            if (methodName != null) relevance += computeRelevanceForCaseMatching(methodName, method.selector);
4999            relevance += computeRelevanceForExpectingType(method.returnType);
5000            relevance += computeRelevanceForStatic(onlyStaticMethods, method.isStatic());
5001            relevance += computeRelevanceForQualification(prefixRequired);
5002            relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
5003            if (onlyStaticMethods && this.insideQualifiedReference) {
5004                relevance += computeRelevanceForInheritance(receiverType, method.declaringClass);
5005            }
5006            if (missingElements != null) {
5007                relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
5008            }
5009            
5010            this.noProposal = false;
5011            // Standard proposal
5012
if(!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
5013                CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
5014                proposal.setDeclarationSignature(getSignature(method.declaringClass));
5015                proposal.setSignature(getSignature(method));
5016                MethodBinding original = method.original();
5017                if(original != method) {
5018                    proposal.setOriginalSignature(getSignature(original));
5019                }
5020                proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
5021                proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
5022                proposal.setParameterPackageNames(parameterPackageNames);
5023                proposal.setParameterTypeNames(parameterTypeNames);
5024                proposal.setPackageName(method.returnType.qualifiedPackageName());
5025                proposal.setTypeName(method.returnType.qualifiedSourceName());
5026                proposal.setName(method.selector);
5027                if (missingElements != null) {
5028                    CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
5029                    for (int i = 0; i < missingElements.length; i++) {
5030                        subProposals[i] =
5031                            createRequiredTypeProposal(
5032                                    missingElements[i],
5033                                    missingElementsStarts[i],
5034                                    missingElementsEnds[i],
5035                                    relevance);
5036                    }
5037                    proposal.setRequiredProposals(subProposals);
5038                }
5039                proposal.setCompletion(completion);
5040                proposal.setFlags(method.modifiers);
5041                proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5042                proposal.setRelevance(relevance);
5043                if(parameterNames != null) proposal.setParameterNames(parameterNames);
5044                this.requestor.accept(proposal);
5045                if(DEBUG) {
5046                    this.printDebug(proposal);
5047                }
5048            }
5049
5050            // Javadoc proposal
5051
if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
5052                char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
5053                CompletionProposal proposal = this.createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition);
5054                proposal.setDeclarationSignature(getSignature(method.declaringClass));
5055                proposal.setSignature(getSignature(method));
5056                MethodBinding original = method.original();
5057                if(original != method) {
5058                    proposal.setOriginalSignature(getSignature(original));
5059                }
5060                proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
5061                proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
5062                proposal.setParameterPackageNames(parameterPackageNames);
5063                proposal.setParameterTypeNames(parameterTypeNames);
5064                proposal.setPackageName(method.returnType.qualifiedPackageName());
5065                proposal.setTypeName(method.returnType.qualifiedSourceName());
5066                proposal.setName(method.selector);
5067                proposal.setCompletion(javadocCompletion);
5068                proposal.setFlags(method.modifiers);
5069                int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
5070                proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
5071                proposal.setRelevance(relevance+R_INLINE_TAG);
5072                if(parameterNames != null) proposal.setParameterNames(parameterNames);
5073                this.requestor.accept(proposal);
5074                if(DEBUG) {
5075                    this.printDebug(proposal);
5076                }
5077            }
5078            this.startPosition = previousStartPosition;
5079        }
5080        
5081        methodsFound.addAll(newMethodsFound);
5082    }
5083    
5084    private void findLocalMethodsFromFavorites(
5085            char[] methodName,
5086            MethodBinding[] methods,
5087            Scope scope,
5088            ObjectVector methodsFound,
5089            ReferenceBinding receiverType,
5090            InvocationSite invocationSite,
5091            Scope invocationScope) {
5092        
5093            char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.');
5094
5095            int methodLength = methodName.length;
5096
5097            next : for (int f = methods.length; --f >= 0;) {
5098                MethodBinding method = methods[f];
5099
5100                if (method.isSynthetic()) continue next;
5101
5102                if (method.isDefaultAbstract()) continue next;
5103
5104                if (method.isConstructor()) continue next;
5105                
5106                if (this.options.checkDeprecation &&
5107                        method.isViewedAsDeprecated() &&
5108                        !scope.isDefinedInSameUnit(method.declaringClass))
5109                    continue next;
5110                
5111                if (!method.isStatic()) continue next;
5112
5113                if (this.options.checkVisibility
5114                    && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
5115
5116                if (methodLength > method.selector.length) continue next;
5117                    
5118                if (!CharOperation.prefixEquals(methodName, method.selector, false /* ignore case */)
5119                        && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) {
5120                    continue next;
5121                }
5122                
5123                for (int i = methodsFound.size; --i >= 0;) {
5124                    Object JavaDoc[] other = (Object JavaDoc[]) methodsFound.elementAt(i);
5125                    MethodBinding otherMethod = (MethodBinding) other[0];
5126                    
5127                    if (method == otherMethod) continue next;
5128                    
5129                    if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
5130                        if (lookupEnvironment.methodVerifier().doesMethodOverride(otherMethod, method)) {
5131                            continue next;
5132                        }
5133                    }
5134                }
5135                
5136                boolean proposeStaticImport = !(this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5) &&
5137                    this.options.suggestStaticImport;
5138                
5139                boolean isAlreadyImported = false;
5140                if (!proposeStaticImport) {
5141                    if(!this.importCachesInitialized) {
5142                        this.initializeImportCaches();
5143                    }
5144                    for (int j = 0; j < this.importCacheCount; j++) {
5145                        char[][] importName = this.importsCache[j];
5146                        if(CharOperation.equals(receiverType.sourceName, importName[0])) {
5147                            if (!CharOperation.equals(typeName, importName[1])) {
5148                                continue next;
5149                            } else {
5150                                isAlreadyImported = true;
5151                            }
5152                        }
5153                    }
5154                }
5155                
5156                methodsFound.add(new Object JavaDoc[]{method, receiverType});
5157                
5158                ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeWithSameErasure(method.declaringClass);
5159                if (method.declaringClass != superTypeWithSameErasure) {
5160                    MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
5161                    for (int i = 0; i < otherMethods.length; i++) {
5162                        if(otherMethods[i].original() == method.original()) {
5163                            method = otherMethods[i];
5164                        }
5165                    }
5166                }
5167                
5168                int length = method.parameters.length;
5169                char[][] parameterPackageNames = new char[length][];
5170                char[][] parameterTypeNames = new char[length][];
5171
5172                for (int i = 0; i < length; i++) {
5173                    TypeBinding type = method.original().parameters[i];
5174                    parameterPackageNames[i] = type.qualifiedPackageName();
5175                    parameterTypeNames[i] = type.qualifiedSourceName();
5176                }
5177                char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
5178
5179                char[] completion = CharOperation.NO_CHAR;
5180                
5181                int previousStartPosition = this.startPosition;
5182                
5183                if (this.source != null
5184                    && this.source.length > this.endPosition
5185                    && this.source[this.endPosition] == '(') {
5186                    completion = method.selector;
5187                } else {
5188                    completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
5189                }
5190                
5191                int relevance = computeBaseRelevance();
5192                relevance += computeRelevanceForResolution();
5193                relevance += computeRelevanceForInterestingProposal();
5194                if (methodName != null) relevance += computeRelevanceForCaseMatching(methodName, method.selector);
5195                relevance += computeRelevanceForExpectingType(method.returnType);
5196                relevance += computeRelevanceForStatic(true, method.isStatic());
5197                relevance += computeRelevanceForQualification(true);
5198                relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
5199
5200                CompilationUnitDeclaration cu = this.unitScope.referenceContext;
5201                int importStart = cu.types[0].declarationSourceStart;
5202                int importEnd = importStart;
5203                
5204                this.noProposal = false;
5205                
5206                if (!proposeStaticImport) {
5207                    if (isAlreadyImported) {
5208                        if (!isIgnored(CompletionProposal.METHOD_REF)) {
5209                            completion = CharOperation.concat(receiverType.sourceName, completion, '.');
5210                            
5211                            CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
5212                            proposal.setDeclarationSignature(getSignature(method.declaringClass));
5213                            proposal.setSignature(getSignature(method));
5214                            MethodBinding original = method.original();
5215                            if(original != method) {
5216                                proposal.setOriginalSignature(getSignature(original));
5217                            }
5218                            proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
5219                            proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
5220                            proposal.setParameterPackageNames(parameterPackageNames);
5221                            proposal.setParameterTypeNames(parameterTypeNames);
5222                            proposal.setPackageName(method.returnType.qualifiedPackageName());
5223                            proposal.setTypeName(method.returnType.qualifiedSourceName());
5224                            proposal.setName(method.selector);
5225                            proposal.setCompletion(completion);
5226                            proposal.setFlags(method.modifiers);
5227                            proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5228                            proposal.setRelevance(relevance);
5229                            if(parameterNames != null) proposal.setParameterNames(parameterNames);
5230                            
5231                            this.requestor.accept(proposal);
5232                            if(DEBUG) {
5233                                this.printDebug(proposal);
5234                            }
5235                        }
5236                    } else if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_IMPORT)) {
5237                        completion = CharOperation.concat(receiverType.sourceName, completion, '.');
5238                        
5239                        CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
5240                        proposal.setDeclarationSignature(getSignature(method.declaringClass));
5241                        proposal.setSignature(getSignature(method));
5242                        MethodBinding original = method.original();
5243                        if(original != method) {
5244                            proposal.setOriginalSignature(getSignature(original));
5245                        }
5246                        proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
5247                        proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
5248                        proposal.setParameterPackageNames(parameterPackageNames);
5249                        proposal.setParameterTypeNames(parameterTypeNames);
5250                        proposal.setPackageName(method.returnType.qualifiedPackageName());
5251                        proposal.setTypeName(method.returnType.qualifiedSourceName());
5252                        proposal.setName(method.selector);
5253                        proposal.setCompletion(completion);
5254                        proposal.setFlags(method.modifiers);
5255                        proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5256                        proposal.setRelevance(relevance);
5257                        if(parameterNames != null) proposal.setParameterNames(parameterNames);
5258                        
5259                        char[] typeImportCompletion = createImportCharArray(typeName, false, false);
5260                        
5261                        CompletionProposal typeImportProposal = this.createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
5262                        typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
5263                        typeImportProposal.completionEngine = this;
5264                        char[] packageName = receiverType.qualifiedPackageName();
5265                        typeImportProposal.setDeclarationSignature(packageName);
5266                        typeImportProposal.setSignature(getSignature(receiverType));
5267                        typeImportProposal.setPackageName(packageName);
5268                        typeImportProposal.setTypeName(receiverType.qualifiedSourceName());
5269                        typeImportProposal.setCompletion(typeImportCompletion);
5270                        typeImportProposal.setFlags(receiverType.modifiers);
5271                        typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
5272                        typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
5273                        typeImportProposal.setRelevance(relevance);
5274                        
5275                        proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
5276                        
5277                        this.requestor.accept(proposal);
5278                        if(DEBUG) {
5279                            this.printDebug(proposal);
5280                        }
5281                    }
5282                } else {
5283                    if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.METHOD_IMPORT)) {
5284                        CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
5285                        proposal.setDeclarationSignature(getSignature(method.declaringClass));
5286                        proposal.setSignature(getSignature(method));
5287                        MethodBinding original = method.original();
5288                        if(original != method) {
5289                            proposal.setOriginalSignature(getSignature(original));
5290                        }
5291                        proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
5292                        proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
5293                        proposal.setParameterPackageNames(parameterPackageNames);
5294                        proposal.setParameterTypeNames(parameterTypeNames);
5295                        proposal.setPackageName(method.returnType.qualifiedPackageName());
5296                        proposal.setTypeName(method.returnType.qualifiedSourceName());
5297                        proposal.setName(method.selector);
5298                        proposal.setCompletion(completion);
5299                        proposal.setFlags(method.modifiers);
5300                        proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5301                        proposal.setRelevance(relevance);
5302                        if(parameterNames != null) proposal.setParameterNames(parameterNames);
5303                        
5304                        char[] methodImportCompletion = createImportCharArray(CharOperation.concat(typeName, method.selector, '.'), true, false);
5305                        
5306                        CompletionProposal methodImportProposal = this.createProposal(CompletionProposal.METHOD_IMPORT, this.actualCompletionPosition);
5307                        methodImportProposal.setDeclarationSignature(getSignature(method.declaringClass));
5308                        methodImportProposal.setSignature(getSignature(method));
5309                        if(original != method) {
5310                            proposal.setOriginalSignature(getSignature(original));
5311                        }
5312                        methodImportProposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
5313                        methodImportProposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
5314                        methodImportProposal.setParameterPackageNames(parameterPackageNames);
5315                        methodImportProposal.setParameterTypeNames(parameterTypeNames);
5316                        methodImportProposal.setPackageName(method.returnType.qualifiedPackageName());
5317                        methodImportProposal.setTypeName(method.returnType.qualifiedSourceName());
5318                        methodImportProposal.setName(method.selector);
5319                        methodImportProposal.setCompletion(methodImportCompletion);
5320                        methodImportProposal.setFlags(method.modifiers);
5321                        methodImportProposal.setAdditionalFlags(CompletionFlags.StaticImport);
5322                        methodImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
5323                        methodImportProposal.setRelevance(relevance);
5324                        if(parameterNames != null) methodImportProposal.setParameterNames(parameterNames);
5325                        
5326                        proposal.setRequiredProposals(new CompletionProposal[]{methodImportProposal});
5327                        
5328                        this.requestor.accept(proposal);
5329                        if(DEBUG) {
5330                            this.printDebug(proposal);
5331                        }
5332                    }
5333                }
5334                
5335                this.startPosition = previousStartPosition;
5336            }
5337        }
5338    
5339    private CompletionProposal createRequiredTypeProposal(Binding binding, int start, int end, int relevance) {
5340        CompletionProposal proposal = null;
5341        if (binding instanceof ReferenceBinding) {
5342            ReferenceBinding typeBinding = (ReferenceBinding) binding;
5343            
5344            char[] packageName = typeBinding.qualifiedPackageName();
5345            char[] typeName = typeBinding.qualifiedSourceName();
5346            char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
5347            
5348            proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
5349            proposal.nameLookup = this.nameEnvironment.nameLookup;
5350            proposal.completionEngine = this;
5351            proposal.setDeclarationSignature(packageName);
5352            proposal.setSignature(getSignature(typeBinding));
5353            proposal.setPackageName(packageName);
5354            proposal.setTypeName(typeName);
5355            proposal.setCompletion(fullyQualifiedName);
5356            proposal.setFlags(typeBinding.modifiers);
5357            proposal.setReplaceRange(start - this.offset, end - this.offset);
5358            proposal.setRelevance(relevance);
5359        } else if (binding instanceof PackageBinding) {
5360            PackageBinding packageBinding = (PackageBinding) binding;
5361            
5362            char[] packageName = CharOperation.concatWith(packageBinding.compoundName, '.');
5363            
5364            proposal = this.createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition);
5365            proposal.setDeclarationSignature(packageName);
5366            proposal.setPackageName(packageName);
5367            proposal.setCompletion(packageName);
5368            proposal.setReplaceRange(start - this.offset, end - this.offset);
5369            proposal.setRelevance(relevance);
5370        }
5371        return proposal;
5372    }
5373
5374    // Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
5375
private void findLocalMethodsOfStaticImports(
5376        char[] methodName,
5377        MethodBinding[] methods,
5378        Scope scope,
5379        ObjectVector methodsFound,
5380        ReferenceBinding receiverType,
5381        InvocationSite invocationSite) {
5382        
5383        ObjectVector newMethodsFound = new ObjectVector();
5384
5385        next : for (int f = methods.length; --f >= 0;) {
5386            MethodBinding method = methods[f];
5387
5388            if (method.isSynthetic()) continue next;
5389
5390            if (method.isDefaultAbstract()) continue next;
5391
5392            if (method.isConstructor()) continue next;
5393
5394            if (!method.isStatic()) continue next;
5395            
5396            if (this.options.checkDeprecation &&
5397                    method.isViewedAsDeprecated() &&
5398                    !scope.isDefinedInSameUnit(method.declaringClass))
5399                continue next;
5400            
5401            if (this.options.checkVisibility
5402                && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
5403
5404            if (!CharOperation.equals(methodName, method.selector, false /* ignore case */)
5405                    && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
5406                continue next;
5407            
5408            for (int i = methodsFound.size; --i >= 0;) {
5409                Object JavaDoc[] other = (Object JavaDoc[]) methodsFound.elementAt(i);
5410                MethodBinding otherMethod = (MethodBinding) other[0];
5411                ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
5412                if (method == otherMethod && receiverType == otherReceiverType)
5413                    continue next;
5414                
5415                if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
5416                    if (lookupEnvironment.methodVerifier().doesMethodOverride(otherMethod, method)) {
5417                        continue next;
5418                    }
5419                }
5420            }
5421
5422            newMethodsFound.add(new Object JavaDoc[]{method, receiverType});
5423
5424            int length = method.parameters.length;
5425            char[][] parameterPackageNames = new char[length][];
5426            char[][] parameterTypeNames = new char[length][];
5427
5428            for (int i = 0; i < length; i++) {
5429                TypeBinding type = method.original().parameters[i];
5430                parameterPackageNames[i] = type.qualifiedPackageName();
5431                parameterTypeNames[i] = type.qualifiedSourceName();
5432            }
5433            char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
5434
5435            char[] completion = CharOperation.NO_CHAR;
5436            
5437            int previousStartPosition = this.startPosition;
5438            
5439            // nothing to insert - do not want to replace the existing selector & arguments
5440
if (this.source != null
5441                && this.source.length > this.endPosition
5442                && this.source[this.endPosition] == '(') {
5443                completion = method.selector;
5444            } else {
5445                completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
5446            }
5447            
5448            int relevance = computeBaseRelevance();
5449            relevance += computeRelevanceForResolution();
5450            relevance += computeRelevanceForInterestingProposal();
5451            relevance += computeRelevanceForCaseMatching(methodName, method.selector);
5452            relevance += computeRelevanceForExpectingType(method.returnType);
5453            relevance += computeRelevanceForStatic(true, method.isStatic());
5454            relevance += computeRelevanceForQualification(false);
5455            relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
5456            
5457            this.noProposal = false;
5458            if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
5459                CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
5460                proposal.setDeclarationSignature(getSignature(method.declaringClass));
5461                proposal.setSignature(getSignature(method));
5462                MethodBinding original = method.original();
5463                if(original != method) {
5464                    proposal.setOriginalSignature(getSignature(original));
5465                }
5466                proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
5467                proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
5468                proposal.setParameterPackageNames(parameterPackageNames);
5469                proposal.setParameterTypeNames(parameterTypeNames);
5470                proposal.setPackageName(method.returnType.qualifiedPackageName());
5471                proposal.setTypeName(method.returnType.qualifiedSourceName());
5472                proposal.setName(method.selector);
5473                proposal.setCompletion(completion);
5474                proposal.setFlags(method.modifiers);
5475                proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5476                proposal.setRelevance(relevance);
5477                if(parameterNames != null) proposal.setParameterNames(parameterNames);
5478                this.requestor.accept(proposal);
5479                if(DEBUG) {
5480                    this.printDebug(proposal);
5481                }
5482            }
5483            this.startPosition = previousStartPosition;
5484        }
5485        
5486        methodsFound.addAll(newMethodsFound);
5487    }
5488    int computeRelevanceForCaseMatching(char[] token, char[] proposalName){
5489        if (this.options.camelCaseMatch) {
5490            if(CharOperation.equals(token, proposalName, true /* do not ignore case */)) {
5491                return R_CASE + R_EXACT_NAME;
5492            } else if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
5493                return R_CASE;
5494            } else if (CharOperation.camelCaseMatch(token, proposalName)){
5495                return R_CAMEL_CASE;
5496            } else if(CharOperation.equals(token, proposalName, false /* ignore case */)) {
5497                return R_EXACT_NAME;
5498            }
5499        } else if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
5500            if(CharOperation.equals(token, proposalName, true /* do not ignore case */)) {
5501                return R_CASE + R_EXACT_NAME;
5502            } else {
5503                return R_CASE;
5504            }
5505        } else if(CharOperation.equals(token, proposalName, false /* ignore case */)) {
5506            return R_EXACT_NAME;
5507        }
5508        return 0;
5509    }
5510    private int computeRelevanceForAnnotation(){
5511        if(this.assistNodeIsAnnotation) {
5512            return R_ANNOTATION;
5513        }
5514        return 0;
5515    }
5516    private int computeRelevanceForAnnotationTarget(TypeBinding typeBinding){
5517        if (this.assistNodeIsAnnotation &&
5518                (this.targetedElement & TagBits.AnnotationTargetMASK) != 0) {
5519            long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
5520            if(target == 0 || (target & this.targetedElement) != 0) {
5521                return R_TARGET;
5522            }
5523        }
5524        return 0;
5525    }
5526    private int computeRelevanceForClass(){
5527        if(this.assistNodeIsClass) {
5528            return R_CLASS;
5529        }
5530        return 0;
5531    }
5532    private int computeRelevanceForEnum(){
5533        if(this.assistNodeIsEnum) {
5534            return R_ENUM;
5535        }
5536        return 0;
5537    }
5538    private int computeRelevanceForInterface(){
5539        if(this.assistNodeIsInterface) {
5540            return R_INTERFACE;
5541        }
5542        return 0;
5543    }
5544    private int computeRelevanceForMissingElements(boolean hasProblems) {
5545        if (!hasProblems) {
5546            return R_NO_PROBLEMS;
5547        }
5548        return 0;
5549    }
5550    int computeRelevanceForQualification(boolean prefixRequired) {
5551        if(!prefixRequired && !this.insideQualifiedReference) {
5552            return R_UNQUALIFIED;
5553        }
5554        
5555        if(prefixRequired && this.insideQualifiedReference) {
5556            return R_QUALIFIED;
5557        }
5558        return 0;
5559    }
5560    int computeRelevanceForRestrictions(int accessRuleKind) {
5561        if(accessRuleKind == IAccessRule.K_ACCESSIBLE) {
5562            return R_NON_RESTRICTED;
5563        }
5564        return 0;
5565    }
5566    private int computeRelevanceForStatic(boolean onlyStatic, boolean isStatic) {
5567        if(this.insideQualifiedReference && !onlyStatic && !isStatic) {
5568            return R_NON_STATIC;
5569        }
5570        return 0;
5571    }
5572    private int computeRelevanceForException(){
5573        if (this.assistNodeIsException) {
5574            return R_EXCEPTION;
5575        }
5576        return 0;
5577    }
5578    private int computeRelevanceForException(char[] proposalName){
5579        
5580        if((this.assistNodeIsException || (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) != 0 )&&
5581            (CharOperation.match(EXCEPTION_PATTERN, proposalName, false) ||
5582            CharOperation.match(ERROR_PATTERN, proposalName, false))) {
5583            return R_EXCEPTION;
5584        }
5585        return 0;
5586    }
5587    private int computeRelevanceForExpectingType(TypeBinding proposalType){
5588        if(this.expectedTypes != null && proposalType != null) {
5589            for (int i = 0; i <= this.expectedTypesPtr; i++) {
5590                int relevance = R_EXPECTED_TYPE;
5591                if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
5592                    CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
5593                    relevance = R_EXACT_EXPECTED_TYPE;
5594                }
5595                if((this.expectedTypesFilter & SUBTYPE) != 0
5596                    && proposalType.isCompatibleWith(this.expectedTypes[i])) {
5597                        return relevance;
5598                }
5599                if((this.expectedTypesFilter & SUPERTYPE) != 0
5600                    && this.expectedTypes[i].isCompatibleWith(proposalType)) {
5601                    return relevance;
5602                }
5603            }
5604        }
5605        return 0;
5606    }
5607    private int computeRelevanceForExpectingType(char[] packageName, char[] typeName){
5608        if(this.expectedTypes != null) {
5609            for (int i = 0; i <= this.expectedTypesPtr; i++) {
5610                if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), packageName) &&
5611                    CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), typeName)) {
5612                    return R_EXACT_EXPECTED_TYPE;
5613                }
5614            }
5615            if(this.hasJavaLangObjectAsExpectedType) {
5616                return R_EXPECTED_TYPE;
5617            }
5618        }
5619        return 0;
5620    }
5621    
5622    private int computeRelevanceForInheritance(ReferenceBinding receiverType, ReferenceBinding declaringClass) {
5623        if (receiverType == declaringClass) return R_NON_INHERITED;
5624        return 0;
5625    }
5626    
5627    int computeRelevanceForInterestingProposal(){
5628        return computeRelevanceForInterestingProposal(null);
5629    }
5630    private int computeRelevanceForInterestingProposal(Binding binding){
5631        if(this.uninterestingBindings != null) {
5632            for (int i = 0; i <= this.uninterestingBindingsPtr; i++) {
5633                if(this.uninterestingBindings[i] == binding) {
5634                    return 0;
5635                }
5636            }
5637        }
5638        return R_INTERESTING;
5639    }
5640    private void computeUninterestingBindings(ASTNode parent, Scope scope){
5641        if(parent instanceof LocalDeclaration) {
5642            addUninterestingBindings(((LocalDeclaration)parent).binding);
5643        } else if (parent instanceof FieldDeclaration) {
5644            addUninterestingBindings(((FieldDeclaration)parent).binding);
5645        }
5646    }
5647    
5648    private void findLabels(char[] label, char[][] choices) {
5649        if(choices == null || choices.length == 0) return;
5650        
5651        int length = label.length;
5652        for (int i = 0; i < choices.length; i++) {
5653            if (length <= choices[i].length
5654                && CharOperation.prefixEquals(label, choices[i], false /* ignore case */
5655            )){
5656                int relevance = computeBaseRelevance();
5657                relevance += computeRelevanceForResolution();
5658                relevance += computeRelevanceForInterestingProposal();
5659                relevance += computeRelevanceForCaseMatching(label, choices[i]);
5660                relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
5661

5662                this.noProposal = false;
5663                if(!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) {
5664                    CompletionProposal proposal = this.createProposal(CompletionProposal.LABEL_REF, this.actualCompletionPosition);
5665                    proposal.setName(choices[i]);
5666                    proposal.setCompletion(choices[i]);
5667                    proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5668                    proposal.setRelevance(relevance);
5669                    this.requestor.accept(proposal);
5670                    if(DEBUG) {
5671                        this.printDebug(proposal);
5672                    }
5673                }
5674            }
5675        }
5676    }
5677    
5678    // Helper method for findMethods(char[], MethodBinding[], Scope, ObjectVector, boolean, boolean, boolean, TypeBinding)
5679
private void findLocalMethodDeclarations(
5680        char[] methodName,
5681        MethodBinding[] methods,
5682        Scope scope,
5683        ObjectVector methodsFound,
5684        // boolean noVoidReturnType, how do you know?
5685
boolean exactMatch,
5686        ReferenceBinding receiverType) {
5687
5688        ObjectVector newMethodsFound = new ObjectVector();
5689        // Inherited methods which are hidden by subclasses are filtered out
5690
// No visibility checks can be performed without the scope & invocationSite
5691
int methodLength = methodName.length;
5692        next : for (int f = methods.length; --f >= 0;) {
5693
5694            MethodBinding method = methods[f];
5695            if (method.isSynthetic()) continue next;
5696                
5697            if (method.isDefaultAbstract()) continue next;
5698            
5699            if (method.isConstructor()) continue next;
5700                
5701            if (method.isFinal()) {
5702                newMethodsFound.add(method);
5703                continue next;
5704            }
5705            
5706            if (this.options.checkDeprecation &&
5707                    method.isViewedAsDeprecated() &&
5708                    !scope.isDefinedInSameUnit(method.declaringClass))
5709                continue next;
5710
5711            // if (noVoidReturnType && method.returnType == BaseTypes.VoidBinding) continue next;
5712
if(method.isStatic()) continue next;
5713
5714            if (!method.canBeSeenBy(receiverType, FakeInvocationSite , scope)) continue next;
5715
5716            if (exactMatch) {
5717                if (!CharOperation.equals(methodName, method.selector, false /* ignore case */
5718                    ))
5719                    continue next;
5720
5721            } else {
5722
5723                if (methodLength > method.selector.length)
5724                    continue next;
5725
5726                if (!CharOperation.prefixEquals(methodName, method.selector, false/* ignore case */)
5727                        && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
5728                    continue next;
5729            }
5730
5731            for (int i = methodsFound.size; --i >= 0;) {
5732                MethodBinding otherMethod = (MethodBinding) methodsFound.elementAt(i);
5733                if (method == otherMethod)
5734                    continue next;
5735
5736                if (CharOperation.equals(method.selector, otherMethod.selector, true)
5737                        && lookupEnvironment.methodVerifier().doesMethodOverride(otherMethod, method)) {
5738                    continue next;
5739                }
5740            }
5741
5742            newMethodsFound.add(method);
5743            
5744            int length = method.parameters.length;
5745            char[][] parameterPackageNames = new char[length][];
5746            char[][] parameterFullTypeNames = new char[length][];
5747            
5748            for (int i = 0; i < length; i++) {
5749                TypeBinding type = method.parameters[i];
5750                parameterPackageNames[i] = type.qualifiedPackageName();
5751                parameterFullTypeNames[i] = type.qualifiedSourceName();
5752            }
5753
5754            char[][] parameterNames = findMethodParameterNames(method, parameterFullTypeNames);
5755            
5756            if(method.typeVariables != null && method.typeVariables.length > 0) {
5757                char[][] excludedNames = findEnclosingTypeNames(scope);
5758                char[][] substituedParameterNames = substituteMethodTypeParameterNames(method.typeVariables, excludedNames);
5759                if(substituedParameterNames != null) {
5760                    method = new ParameterizedMethodBinding(
5761                                method.declaringClass,
5762                                method,
5763                                substituedParameterNames,
5764                                scope.environment());
5765                }
5766            }
5767            
5768            StringBuffer JavaDoc completion = new StringBuffer JavaDoc(10);
5769            if (!exactMatch) {
5770                createMethod(method, parameterPackageNames, parameterFullTypeNames, parameterNames, completion);
5771            }
5772
5773            int relevance = computeBaseRelevance();
5774            relevance += computeRelevanceForResolution();
5775            relevance += computeRelevanceForInterestingProposal();
5776            relevance += computeRelevanceForCaseMatching(methodName, method.selector);
5777            relevance += R_METHOD_OVERIDE;
5778            if(method.isAbstract()) relevance += R_ABSTRACT_METHOD;
5779            relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
5780            
5781            this.noProposal = false;
5782            if(!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
5783                CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_DECLARATION, this.actualCompletionPosition);
5784                proposal.setDeclarationSignature(getSignature(method.declaringClass));
5785                proposal.setDeclarationKey(method.declaringClass.computeUniqueKey());
5786                proposal.setSignature(getSignature(method));
5787                MethodBinding original = method.original();
5788                if(original != method) {
5789                    proposal.setOriginalSignature(getSignature(original));
5790                }
5791                proposal.setKey(method.computeUniqueKey());
5792                proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
5793                proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
5794                proposal.setParameterPackageNames(parameterPackageNames);
5795                proposal.setParameterTypeNames(parameterFullTypeNames);
5796                proposal.setPackageName(method.returnType.qualifiedPackageName());
5797                proposal.setTypeName(method.returnType.qualifiedSourceName());
5798                proposal.setCompletion(completion.toString().toCharArray());
5799                proposal.setName(method.selector);
5800                proposal.setFlags(method.modifiers);
5801                proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5802                proposal.setRelevance(relevance);
5803                if(parameterNames != null) proposal.setParameterNames(parameterNames);
5804                this.requestor.accept(proposal);
5805                if(DEBUG) {
5806                    this.printDebug(proposal);
5807                }
5808            }
5809        }
5810        methodsFound.addAll(newMethodsFound);
5811    }
5812    
5813    private void createTypeVariable(TypeVariableBinding typeVariable, StringBuffer JavaDoc completion) {
5814        completion.append(typeVariable.sourceName);
5815        
5816        if (typeVariable.superclass != null && typeVariable.firstBound == typeVariable.superclass) {
5817            completion.append(' ');
5818            completion.append(EXTENDS);
5819            completion.append(' ');
5820            createType(typeVariable.superclass, completion);
5821        }
5822        if (typeVariable.superInterfaces != null && typeVariable.superInterfaces != Binding.NO_SUPERINTERFACES) {
5823           if (typeVariable.firstBound != typeVariable.superclass) {
5824               completion.append(' ');
5825               completion.append(EXTENDS);
5826               completion.append(' ');
5827           }
5828           for (int i = 0, length = typeVariable.superInterfaces.length; i < length; i++) {
5829               if (i > 0 || typeVariable.firstBound == typeVariable.superclass) {
5830                   completion.append(' ');
5831                   completion.append(EXTENDS);
5832                   completion.append(' ');
5833               }
5834               createType(typeVariable.superInterfaces[i], completion);
5835           }
5836        }
5837    }
5838    
5839    private void createType(TypeBinding type, StringBuffer JavaDoc completion) {
5840        if (type.isBaseType()) {
5841            completion.append(type.sourceName());
5842        } else if (type.isTypeVariable()) {
5843            completion.append(type.sourceName());
5844        } else if (type.isWildcard()) {
5845            WildcardBinding wildcardBinding = (WildcardBinding) type;
5846            completion.append('?');
5847            switch (wildcardBinding.boundKind) {
5848                case Wildcard.EXTENDS:
5849                    completion.append(' ');
5850                    completion.append(EXTENDS);
5851                    completion.append(' ');
5852                    createType(wildcardBinding.bound, completion);
5853                    if(wildcardBinding.otherBounds != null) {
5854                        
5855                        int length = wildcardBinding.otherBounds.length;
5856                        for (int i = 0; i < length; i++) {
5857                            completion.append(' ');
5858                            completion.append('&');
5859                            completion.append(' ');
5860                            createType(wildcardBinding.otherBounds[i], completion);
5861                        }
5862                    }
5863                    break;
5864                case Wildcard.SUPER:
5865                    completion.append(' ');
5866                    completion.append(SUPER);
5867                    completion.append(' ');
5868                    createType(wildcardBinding.bound, completion);
5869                    break;
5870            }
5871        } else if (type.isArrayType()) {
5872            createType(type.leafComponentType(), completion);
5873            int dim = type.dimensions();
5874            for (int i = 0; i < dim; i++) {
5875                completion.append('[');
5876                completion.append(']');
5877            }
5878        } else if (type.isParameterizedType()) {
5879            ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) type;
5880            if (type.isMemberType()) {
5881                createType(parameterizedType.enclosingType(), completion);
5882                completion.append('.');
5883                completion.append(parameterizedType.sourceName);
5884            } else {
5885                completion.append(CharOperation.concatWith(parameterizedType.genericType().compoundName, '.'));
5886            }
5887            if (parameterizedType.arguments != null) {
5888                completion.append('<');
5889                for (int i = 0, length = parameterizedType.arguments.length; i < length; i++) {
5890                    if (i != 0) completion.append(',');
5891                    createType(parameterizedType.arguments[i], completion);
5892                }
5893                completion.append('>');
5894            }
5895        } else {
5896            char[] packageName = type.qualifiedPackageName();
5897            char[] typeName = type.qualifiedSourceName();
5898            if(mustQualifyType(
5899                    packageName,
5900                    type.sourceName(),
5901                    type.isMemberType() ? type.enclosingType().qualifiedSourceName() : null,
5902                    ((ReferenceBinding)type).modifiers)) {
5903                completion.append(CharOperation.concat(packageName, typeName,'.'));
5904            } else {
5905                completion.append(type.sourceName());
5906            }
5907        }
5908    }
5909    
5910    private void createVargsType(TypeBinding type, StringBuffer JavaDoc completion) {
5911        if (type.isArrayType()) {
5912            createType(type.leafComponentType(), completion);
5913            int dim = type.dimensions() - 1;
5914            for (int i = 0; i < dim; i++) {
5915                completion.append('[');
5916                completion.append(']');
5917            }
5918            completion.append(VARARGS);
5919        } else {
5920            createType(type, completion);
5921        }
5922    }
5923    private char[] createImportCharArray(char[] importedElement, boolean isStatic, boolean onDemand) {
5924        char[] result = IMPORT;
5925        if (isStatic) {
5926            result = CharOperation.concat(result, STATIC, ' ');
5927        }
5928        result = CharOperation.concat(result, importedElement, ' ');
5929        if (onDemand) {
5930            result = CharOperation.concat(result, ON_DEMAND);
5931        }
5932        return CharOperation.concat(result, IMPORT_END);
5933    }
5934    private void createMethod(MethodBinding method, char[][] parameterPackageNames, char[][] parameterTypeNames, char[][] parameterNames, StringBuffer JavaDoc completion) {
5935        //// Modifiers
5936
// flush uninteresting modifiers
5937
int insertedModifiers = method.modifiers & ~(ClassFileConstants.AccNative | ClassFileConstants.AccAbstract);
5938        if(insertedModifiers != ClassFileConstants.AccDefault){
5939            ASTNode.printModifiers(insertedModifiers, completion);
5940        }
5941        
5942        //// Type parameters
5943

5944        TypeVariableBinding[] typeVariableBindings = method.typeVariables;
5945        if(typeVariableBindings != null && typeVariableBindings.length != 0) {
5946            completion.append('<');
5947            for (int i = 0; i < typeVariableBindings.length; i++) {
5948                if(i != 0) {
5949                    completion.append(',');
5950                    completion.append(' ');
5951                }
5952                createTypeVariable(typeVariableBindings[i], completion);
5953            }
5954            completion.append('>');
5955            completion.append(' ');
5956        }
5957        
5958        //// Return type
5959
createType(method.returnType, completion);
5960        completion.append(' ');
5961        
5962        //// Selector
5963
completion.append(method.selector);
5964        
5965        completion.append('(');
5966
5967        ////Parameters
5968
TypeBinding[] parameterTypes = method.parameters;
5969        int length = parameterTypes.length;
5970        for (int i = 0; i < length; i++) {
5971            if(i != 0) {
5972                completion.append(',');
5973                completion.append(' ');
5974            }
5975            createType(parameterTypes[i], completion);
5976            completion.append(' ');
5977            if(parameterNames != null){
5978                completion.append(parameterNames[i]);
5979            } else {
5980                completion.append('%');
5981            }
5982        }
5983        
5984        completion.append(')');
5985        
5986        //// Exceptions
5987
ReferenceBinding[] exceptions = method.thrownExceptions;
5988        
5989        if (exceptions != null && exceptions.length > 0){
5990            completion.append(' ');
5991            completion.append(THROWS);
5992            completion.append(' ');
5993            for(int i = 0; i < exceptions.length ; i++){
5994                if(i != 0) {
5995                    completion.append(' ');
5996                    completion.append(',');
5997                }
5998                createType(exceptions[i], completion);
5999            }
6000        }
6001    }
6002
6003    private boolean isIgnored(int kind, boolean missingTypes) {
6004        return this.requestor.isIgnored(kind) ||
6005            (missingTypes && !this.requestor.isAllowingRequiredProposals(kind, CompletionProposal.TYPE_REF));
6006    }
6007    
6008    private boolean isIgnored(int kind) {
6009        return this.requestor.isIgnored(kind);
6010    }
6011    
6012    private boolean isIgnored(int kind, int requiredProposalKind) {
6013        return this.requestor.isIgnored(kind) ||
6014            !this.requestor.isAllowingRequiredProposals(kind, requiredProposalKind);
6015    }
6016    
6017    private void findMethods(
6018        char[] selector,
6019        TypeBinding[] typeArgTypes,
6020        TypeBinding[] argTypes,
6021        ReferenceBinding receiverType,
6022        Scope scope,
6023        ObjectVector methodsFound,
6024        boolean onlyStaticMethods,
6025        boolean exactMatch,
6026        boolean isCompletingDeclaration,
6027        InvocationSite invocationSite,
6028        Scope invocationScope,
6029        boolean implicitCall,
6030        boolean superCall,
6031        boolean canBePrefixed,
6032        Binding[] missingElements,
6033        int[] missingElementsStarts,
6034        int[] missingElementsEnds,
6035        boolean missingElementsHaveProblems) {
6036
6037        boolean notInJavadoc = this.assistNodeInJavadoc == 0;
6038        if (selector == null && notInJavadoc) {
6039            return;
6040        }
6041        
6042        if(isCompletingDeclaration) {
6043            MethodBinding[] methods = receiverType.availableMethods();
6044            if (methods != null){
6045                for (int i = 0; i < methods.length; i++) {
6046                    if(!methods[i].isDefaultAbstract()) {
6047                        methodsFound.add(methods[i]);
6048                    }
6049                }
6050            }
6051        }
6052        
6053        ReferenceBinding currentType = receiverType;
6054        if (notInJavadoc) {
6055            if (receiverType.isInterface()) {
6056                if (isCompletingDeclaration) {
6057                    findInterfacesMethods(
6058                        selector,
6059                        typeArgTypes,
6060                        argTypes,
6061                        receiverType,
6062                        currentType.superInterfaces(),
6063                        scope,
6064                        methodsFound,
6065                        onlyStaticMethods,
6066                        exactMatch,
6067                        isCompletingDeclaration,
6068                        invocationSite,
6069                        invocationScope,
6070                        implicitCall,
6071                        superCall,
6072                        canBePrefixed,
6073                        missingElements,
6074                        missingElementsStarts,
6075                        missingElementsEnds,
6076                        missingElementsHaveProblems);
6077                } else {
6078                    findInterfacesMethods(
6079                        selector,
6080                        typeArgTypes,
6081                        argTypes,
6082                        receiverType,
6083                        new ReferenceBinding[]{currentType},
6084                        scope,
6085                        methodsFound,
6086                        onlyStaticMethods,
6087                        exactMatch,
6088                        isCompletingDeclaration,
6089                        invocationSite,
6090                        invocationScope,
6091                        implicitCall,
6092                        superCall,
6093                        canBePrefixed,
6094                        missingElements,
6095                        missingElementsStarts,
6096                        missingElementsEnds,
6097                        missingElementsHaveProblems);
6098                }
6099                
6100                currentType = scope.getJavaLangObject();
6101            } else {
6102                if (isCompletingDeclaration){
6103                    findInterfacesMethods(
6104                        selector,
6105                        typeArgTypes,
6106                        argTypes,
6107                        receiverType,
6108                        currentType.superInterfaces(),
6109                        scope,
6110                        methodsFound,
6111                        onlyStaticMethods,
6112                        exactMatch,
6113                        isCompletingDeclaration,
6114                        invocationSite,
6115                        invocationScope,
6116                        implicitCall,
6117                        superCall,
6118                        canBePrefixed,
6119                        missingElements,
6120                        missingElementsStarts,
6121                        missingElementsEnds,
6122                        missingElementsHaveProblems);
6123                    
6124                    currentType = receiverType.superclass();
6125                }
6126            }
6127        }
6128        boolean hasPotentialDefaultAbstractMethods = true;
6129        while (currentType != null) {
6130            
6131            MethodBinding[] methods = currentType.availableMethods();
6132            if (methods != null) {
6133                if (isCompletingDeclaration){
6134                    findLocalMethodDeclarations(
6135                        selector,
6136                        methods,
6137                        scope,
6138                        methodsFound,
6139                        exactMatch,
6140                        receiverType);
6141                } else{
6142                    findLocalMethods(
6143                        selector,
6144                        typeArgTypes,
6145                        argTypes,
6146                        methods,
6147                        scope,
6148                        methodsFound,
6149                        onlyStaticMethods,
6150                        exactMatch,
6151                        receiverType,
6152                        invocationSite,
6153                        invocationScope,
6154                        implicitCall,
6155                        superCall,
6156                        canBePrefixed,
6157                        missingElements,
6158                        missingElementsStarts,
6159                        missingElementsEnds,
6160                        missingElementsHaveProblems);
6161                }
6162            }
6163            
6164            if (notInJavadoc &&
6165                    hasPotentialDefaultAbstractMethods &&
6166                    (currentType.isAbstract() || currentType.isTypeVariable() || currentType.isIntersectionType())){
6167                
6168                ReferenceBinding[] superInterfaces = currentType.superInterfaces();
6169                if (superInterfaces != null && currentType.isIntersectionType()) {
6170                    for (int i = 0; i < superInterfaces.length; i++) {
6171                        superInterfaces[i] = (ReferenceBinding)superInterfaces[i].capture(invocationScope, invocationSite.sourceEnd());
6172                    }
6173                }
6174                
6175                findInterfacesMethods(
6176                    selector,
6177                    typeArgTypes,
6178                    argTypes,
6179                    receiverType,
6180                    superInterfaces,
6181                    scope,
6182                    methodsFound,
6183                    onlyStaticMethods,
6184                    exactMatch,
6185                    isCompletingDeclaration,
6186                    invocationSite,
6187                    invocationScope,
6188                    implicitCall,
6189                    superCall,
6190                    canBePrefixed,
6191                    missingElements,
6192                    missingElementsStarts,
6193                    missingElementsEnds,
6194                    missingElementsHaveProblems);
6195            } else {
6196                hasPotentialDefaultAbstractMethods = false;
6197            }
6198            if(currentType.isParameterizedType()) {
6199                currentType = ((ParameterizedTypeBinding)currentType).genericType().superclass();
6200            } else {
6201                currentType = currentType.superclass();
6202            }
6203        }
6204    }
6205    private char[][] findMethodParameterNames(MethodBinding method, char[][] parameterTypeNames){
6206        TypeBinding erasure = method.declaringClass.erasure();
6207        if(!(erasure instanceof ReferenceBinding)) return null;
6208
6209        char[][] parameterNames = null;
6210        
6211        int length = parameterTypeNames.length;
6212
6213        if (length == 0){
6214            return CharOperation.NO_CHAR_CHAR;
6215        }
6216        // look into the corresponding unit if it is available
6217
if (erasure instanceof SourceTypeBinding){
6218            SourceTypeBinding sourceType = (SourceTypeBinding) erasure;
6219
6220            if (sourceType.scope != null){
6221                TypeDeclaration parsedType;
6222
6223                if ((parsedType = sourceType.scope.referenceContext) != null){
6224                    AbstractMethodDeclaration methodDecl = parsedType.declarationOf(method.original());
6225
6226                    if (methodDecl != null){
6227                        Argument[] arguments = methodDecl.arguments;
6228                        parameterNames = new char[length][];
6229
6230                        for(int i = 0 ; i < length ; i++){
6231                            parameterNames[i] = arguments[i].name;
6232                        }
6233                    }
6234                }
6235            }
6236        }
6237        // look into the model
6238
if(parameterNames == null){
6239            
6240            ReferenceBinding bindingType = (ReferenceBinding)erasure;
6241            
6242            char[] compoundName = CharOperation.concatWith(bindingType.compoundName, '.');
6243            Object JavaDoc type = this.typeCache.get(compoundName);
6244            
6245            ISourceType sourceType = null;
6246            if(type != null) {
6247                if(type instanceof ISourceType) {
6248                    sourceType = (ISourceType) type;
6249                }
6250            } else {
6251                NameEnvironmentAnswer answer = this.nameEnvironment.findType(bindingType.compoundName);
6252                if(answer != null && answer.isSourceType()) {
6253                    sourceType = answer.getSourceTypes()[0];
6254                    this.typeCache.put(compoundName, sourceType);
6255                }
6256            }
6257            
6258            if(sourceType != null) {
6259                IType typeHandle = ((SourceTypeElementInfo) sourceType).getHandle();
6260                
6261                String JavaDoc[] parameterTypeSignatures = new String JavaDoc[length];
6262                for (int i = 0; i < length; i++) {
6263                    parameterTypeSignatures[i] = Signature.createTypeSignature(parameterTypeNames[i], false);
6264                }
6265                IMethod searchedMethod = typeHandle.getMethod(String.valueOf(method.selector), parameterTypeSignatures);
6266                IMethod[] foundMethods = typeHandle.findMethods(searchedMethod);
6267                
6268                if(foundMethods != null) {
6269                    int len = foundMethods.length;
6270                    if(len == 1) {
6271                        try {
6272                            SourceMethod sourceMethod = (SourceMethod) foundMethods[0];
6273                            parameterNames = ((SourceMethodElementInfo) sourceMethod.getElementInfo()).getArgumentNames();
6274                        } catch (JavaModelException e) {
6275                            // method doesn't exist: ignore
6276
}
6277                    }
6278                }
6279            }
6280        }
6281        return parameterNames;
6282    }
6283    
6284    private void findNestedTypes(
6285        char[] typeName,
6286        SourceTypeBinding currentType,
6287        Scope scope,
6288        boolean proposeAllMemberTypes,
6289        ObjectVector typesFound) {
6290        if (typeName == null)
6291            return;
6292
6293        int typeLength = typeName.length;
6294
6295        SourceTypeBinding nextTypeToIgnore = null;
6296        while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found
6297

6298            switch (scope.kind) {
6299
6300                case Scope.METHOD_SCOPE :
6301                case Scope.BLOCK_SCOPE :
6302                    BlockScope blockScope = (BlockScope) scope;
6303
6304                    next : for (int i = 0, length = blockScope.subscopeCount; i < length; i++) {
6305
6306                        if (blockScope.subscopes[i] instanceof ClassScope) {
6307                            SourceTypeBinding localType =
6308                                ((ClassScope) blockScope.subscopes[i]).referenceContext.binding;
6309
6310                            if (!localType.isAnonymousType()) {
6311                                if (this.isForbidden(localType))
6312                                    continue next;
6313                                
6314                                if (typeLength > localType.sourceName.length)
6315                                    continue next;
6316                                if (!CharOperation.prefixEquals(typeName, localType.sourceName, false/* ignore case */)
6317                                        && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, localType.sourceName)))
6318                                    continue next;
6319                                
6320                                for (int j = typesFound.size; --j >= 0;) {
6321                                    ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
6322
6323                                    if (localType == otherType)
6324                                        continue next;
6325                                }
6326                                
6327                                if(this.assistNodeIsClass) {
6328                                    if(!localType.isClass()) continue next;
6329                                } else if(this.assistNodeIsInterface) {
6330                                    if(!localType.isInterface() && !localType.isAnnotationType()) continue next;
6331                                } else if (this.assistNodeIsAnnotation) {
6332                                    if(!localType.isAnnotationType()) continue next;
6333                                }
6334
6335                                int relevance = computeBaseRelevance();
6336                                relevance += computeRelevanceForResolution();
6337                                relevance += computeRelevanceForInterestingProposal();
6338                                relevance += computeRelevanceForCaseMatching(typeName, localType.sourceName);
6339                                relevance += computeRelevanceForExpectingType(localType);
6340                                relevance += computeRelevanceForException(localType.sourceName);
6341                                relevance += computeRelevanceForClass();
6342                                relevance += computeRelevanceForQualification(false);
6343                                relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for nested type
6344
relevance += computeRelevanceForAnnotationTarget(localType);
6345                                
6346                                this.noProposal = false;
6347                                if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
6348                                    createTypeProposal(localType, localType.sourceName, IAccessRule.K_ACCESSIBLE, localType.sourceName, relevance);
6349                                }
6350                            }
6351                        }
6352                    }
6353                    break;
6354
6355                case Scope.CLASS_SCOPE :
6356                    SourceTypeBinding enclosingSourceType = scope.enclosingSourceType();
6357                    findMemberTypes(typeName, enclosingSourceType, scope, currentType, false, false, false, false, proposeAllMemberTypes, nextTypeToIgnore, typesFound);
6358                    nextTypeToIgnore = enclosingSourceType;
6359                    if (typeLength == 0)
6360                        return; // do not search outside the class scope if no prefix was provided
6361
break;
6362
6363                case Scope.COMPILATION_UNIT_SCOPE :
6364                    return;
6365            }
6366            scope = scope.parent;
6367        }
6368    }
6369
6370    private void findPackages(CompletionOnPackageReference packageStatement) {
6371
6372        this.completionToken = CharOperation.concatWith(packageStatement.tokens, '.');
6373        if (this.completionToken.length == 0)
6374            return;
6375
6376        setSourceRange(packageStatement.sourceStart, packageStatement.sourceEnd);
6377        this.nameEnvironment.findPackages(CharOperation.toLowerCase(this.completionToken), this);
6378    }
6379
6380    private void findParameterizedType(TypeReference ref, Scope scope) {
6381        ReferenceBinding refBinding = (ReferenceBinding) ref.resolvedType;
6382        if(refBinding != null) {
6383            if (this.options.checkDeprecation &&
6384                    refBinding.isViewedAsDeprecated() &&
6385                    !scope.isDefinedInSameUnit(refBinding))
6386                return;
6387            
6388            int accessibility = IAccessRule.K_ACCESSIBLE;
6389            if(refBinding.hasRestrictedAccess()) {
6390                AccessRestriction accessRestriction = lookupEnvironment.getAccessRestriction(refBinding);
6391                if(accessRestriction != null) {
6392                    switch (accessRestriction.getProblemId()) {
6393                        case IProblem.ForbiddenReference:
6394                            if (this.options.checkForbiddenReference) {
6395                                return;
6396                            }
6397                            accessibility = IAccessRule.K_NON_ACCESSIBLE;
6398                            break;
6399                        case IProblem.DiscouragedReference:
6400                            if (this.options.checkDiscouragedReference) {
6401                                return;
6402                            }
6403                            accessibility = IAccessRule.K_DISCOURAGED;
6404                            break;
6405                    }
6406                }
6407            }
6408
6409            int relevance = computeBaseRelevance();
6410            relevance += computeRelevanceForResolution();
6411            relevance += computeRelevanceForInterestingProposal();
6412            relevance += computeRelevanceForCaseMatching(refBinding.sourceName, refBinding.sourceName);
6413            relevance += computeRelevanceForExpectingType(refBinding);
6414            relevance += computeRelevanceForQualification(false);
6415            relevance += computeRelevanceForRestrictions(accessibility); // no access restriction for type in the current unit
6416

6417            if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
6418                createTypeProposal(refBinding, refBinding.qualifiedSourceName(), IAccessRule.K_ACCESSIBLE, CharOperation.NO_CHAR, relevance);
6419            }
6420        }
6421    }
6422    private void findTypeParameters(char[] token, Scope scope) {
6423        if (this.compilerOptions.sourceLevel < ClassFileConstants.JDK1_5) return;
6424        
6425        TypeParameter[] typeParameters = null;
6426        while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found
6427
typeParameters = null;
6428            switch (scope.kind) {
6429                case Scope.METHOD_SCOPE :
6430                    MethodScope methodScope = (MethodScope) scope;
6431                    if(methodScope.referenceContext instanceof MethodDeclaration) {
6432                        MethodDeclaration methodDeclaration = (MethodDeclaration) methodScope.referenceContext;
6433                        typeParameters = methodDeclaration.typeParameters;
6434                    } else if(methodScope.referenceContext instanceof ConstructorDeclaration) {
6435                        ConstructorDeclaration methodDeclaration = (ConstructorDeclaration) methodScope.referenceContext;
6436                        typeParameters = methodDeclaration.typeParameters;
6437                    }
6438                    break;
6439                case Scope.CLASS_SCOPE :
6440                    ClassScope classScope = (ClassScope) scope;
6441                    typeParameters = classScope.referenceContext.typeParameters;
6442                    break;
6443                case Scope.COMPILATION_UNIT_SCOPE :
6444                    return;
6445            }
6446            if(typeParameters != null) {
6447                for (int i = 0; i < typeParameters.length; i++) {
6448                    int typeLength = token.length;
6449                    TypeParameter typeParameter = typeParameters[i];
6450                    
6451                    if(typeParameter.binding == null) continue;
6452                    
6453                    if (typeLength > typeParameter.name.length) continue;
6454                    
6455                    if (!CharOperation.prefixEquals(token, typeParameter.name, false)
6456                            && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeParameter.name))) continue;
6457    
6458                    int relevance = computeBaseRelevance();
6459                    relevance += computeRelevanceForResolution();
6460                    relevance += computeRelevanceForInterestingProposal();
6461                    relevance += computeRelevanceForCaseMatching(token, typeParameter.name);
6462                    relevance += computeRelevanceForExpectingType(typeParameter.type == null ? null :typeParameter.type.resolvedType);
6463                    relevance += computeRelevanceForQualification(false);
6464                    relevance += computeRelevanceForException(typeParameter.name);
6465                    relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction fot type parameter
6466

6467                    this.noProposal = false;
6468                    if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
6469                        createTypeParameterProposal(typeParameter, relevance);
6470                    }
6471                }
6472            }
6473            scope = scope.parent;
6474        }
6475    }
6476    private void findTypesAndPackages(char[] token, Scope scope, ObjectVector typesFound) {
6477
6478        if (token == null)
6479            return;
6480        
6481        // do not propose type if completion token is empty
6482
boolean skip = false;
6483        if (token.length == 0 && NO_TYPE_COMPLETION_ON_EMPTY_TOKEN) {
6484            if(!assistNodeIsConstructor && (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) == 0) {
6485                return;
6486            }
6487            skip = true;
6488        }
6489        
6490        boolean proposeType =
6491            !this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
6492            ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
6493        
6494        boolean proposeAllMemberTypes = !this.assistNodeIsConstructor;
6495        
6496        if (!skip && proposeType && scope.enclosingSourceType() != null) {
6497            findNestedTypes(token, scope.enclosingSourceType(), scope, proposeAllMemberTypes, typesFound);
6498            if((!assistNodeIsConstructor && !assistNodeIsAnnotation) && this.assistNodeInJavadoc == 0) {
6499                // don't propose type parameters if the completion is a constructor ('new |')
6500
findTypeParameters(token, scope);
6501            }
6502        }
6503        
6504        boolean isEmptyPrefix = token.length == 0;
6505
6506        if (!skip && proposeType && this.unitScope != null) {
6507            ReferenceBinding outerInvocationType = scope.enclosingSourceType();
6508            if(outerInvocationType != null) {
6509                ReferenceBinding temp = outerInvocationType.enclosingType();
6510                while(temp != null) {
6511                    outerInvocationType = temp;
6512                    temp = temp.enclosingType();
6513                }
6514            }
6515            
6516            int typeLength = token.length;
6517            SourceTypeBinding[] types = this.unitScope.topLevelTypes;
6518
6519            next : for (int i = 0, length = types.length; i < length; i++) {
6520                SourceTypeBinding sourceType = types[i];
6521                
6522                if(isForbidden(sourceType)) continue next;
6523                
6524                if(proposeAllMemberTypes &&
6525                    sourceType != outerInvocationType) {
6526                    findSubMemberTypes(
6527                            token,
6528                            sourceType,
6529                            scope,
6530                            scope.enclosingSourceType(),
6531                            false,
6532                            false,
6533                            false,
6534                            typesFound);
6535                }
6536                
6537                if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue next;
6538                if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue next;
6539
6540                if (typeLength > sourceType.sourceName.length) continue next;
6541                
6542                if (!CharOperation.prefixEquals(token, sourceType.sourceName, false)
6543                        && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName))) continue;
6544    
6545                if (this.assistNodeIsAnnotation && !hasPossibleAnnotationTarget(sourceType, scope)) {
6546                    continue next;
6547                }
6548
6549                for (int j = typesFound.size; --j >= 0;) {
6550                    ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
6551    
6552                    if (sourceType == otherType) continue next;
6553                }
6554                
6555                this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this);
6556                
6557                if(this.assistNodeIsClass) {
6558                    if(!sourceType.isClass()) continue next;
6559                } else if(this.assistNodeIsInterface) {
6560                    if(!sourceType.isInterface() && !sourceType.isAnnotationType()) continue next;
6561                } else if (this.assistNodeIsAnnotation) {
6562                    if(!sourceType.isAnnotationType()) continue next;
6563                } else if (isEmptyPrefix && this.assistNodeIsException) {
6564                    if (sourceType.findSuperTypeErasingTo(TypeIds.T_JavaLangThrowable, true) == null) {
6565                        continue next;
6566                    }
6567                }
6568                
6569                int relevance = computeBaseRelevance();
6570                relevance += computeRelevanceForResolution();
6571                relevance += computeRelevanceForInterestingProposal();
6572                relevance += computeRelevanceForCaseMatching(token, sourceType.sourceName);
6573                relevance += computeRelevanceForExpectingType(sourceType);
6574                relevance += computeRelevanceForQualification(false);
6575                relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for type in the current unit
6576

6577                if (sourceType.isAnnotationType()) {
6578                    relevance += computeRelevanceForAnnotation();
6579                    relevance += computeRelevanceForAnnotationTarget(sourceType);
6580                } else if (sourceType.isInterface()) {
6581                    relevance += computeRelevanceForInterface();
6582                } else if(sourceType.isClass()){
6583                    relevance += computeRelevanceForClass();
6584                    relevance += computeRelevanceForException(sourceType.sourceName);
6585                }
6586                this.noProposal = false;
6587                if(proposeType) {
6588                    char[] typeName = sourceType.sourceName();
6589                    createTypeProposal(sourceType, typeName, IAccessRule.K_ACCESSIBLE, typeName, relevance);
6590                }
6591            }
6592        }
6593        
6594        if(!skip && proposeType) {
6595            this.findTypesFromStaticImports(token, scope, proposeAllMemberTypes, typesFound);
6596        }
6597        
6598        if (isEmptyPrefix && !this.assistNodeIsAnnotation) {
6599            if(proposeType && this.expectedTypesPtr > -1) {
6600                next : for (int i = 0; i <= this.expectedTypesPtr; i++) {
6601                    if(this.expectedTypes[i] instanceof ReferenceBinding) {
6602                        ReferenceBinding refBinding = (ReferenceBinding)this.expectedTypes[i];
6603                        
6604                        if(refBinding.isTypeVariable() && assistNodeIsConstructor) {
6605                            // don't propose type variable if the completion is a constructor ('new |')
6606
continue next;
6607                        }
6608                        if (this.options.checkDeprecation &&
6609                                refBinding.isViewedAsDeprecated() &&
6610                                !scope.isDefinedInSameUnit(refBinding))
6611                            continue next;
6612                        
6613                        int accessibility = IAccessRule.K_ACCESSIBLE;
6614                        if(refBinding.hasRestrictedAccess()) {
6615                            AccessRestriction accessRestriction = lookupEnvironment.getAccessRestriction(refBinding);
6616                            if(accessRestriction != null) {
6617                                switch (accessRestriction.getProblemId()) {
6618                                    case IProblem.ForbiddenReference:
6619                                        if (this.options.checkForbiddenReference) {
6620                                            continue next;
6621                                        }
6622                                        accessibility = IAccessRule.K_NON_ACCESSIBLE;
6623                                        break;
6624                                    case IProblem.DiscouragedReference:
6625                                        if (this.options.checkDiscouragedReference) {
6626                                            continue next;
6627                                        }
6628                                        accessibility = IAccessRule.K_DISCOURAGED;
6629                                        break;
6630                                }
6631                            }
6632                        }
6633                        
6634                        for (int j = 0; j < typesFound.size(); j++) {
6635                            ReferenceBinding typeFound = (ReferenceBinding)typesFound.elementAt(j);
6636                            if (typeFound == refBinding) {
6637                                continue next;
6638                            }
6639                        }
6640                        
6641                        boolean inSameUnit = this.unitScope.isDefinedInSameUnit(refBinding);
6642                        
6643                        // top level types of the current unit are already proposed.
6644
if(skip || !inSameUnit || (inSameUnit && refBinding.isMemberType())) {
6645                            char[] packageName = refBinding.qualifiedPackageName();
6646                            char[] typeName = refBinding.sourceName();
6647                            char[] completionName = typeName;
6648                            
6649                            boolean isQualified = false;
6650                            if (!this.insideQualifiedReference && !refBinding.isMemberType()) {
6651                                if (mustQualifyType(packageName, typeName, null, refBinding.modifiers)) {
6652                                    if (packageName == null || packageName.length == 0)
6653                                        if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
6654                                            continue next; // ignore types from the default package from outside it
6655
completionName = CharOperation.concat(packageName, typeName, '.');
6656                                    isQualified = true;
6657                                }
6658                            }
6659                            
6660                            if(this.assistNodeIsClass) {
6661                                if(!refBinding.isClass()) continue next;
6662                            } else if(this.assistNodeIsInterface) {
6663                                if(!refBinding.isInterface() && !refBinding.isAnnotationType()) continue next;
6664                            } else if (this.assistNodeIsAnnotation) {
6665                                if(!refBinding.isAnnotationType()) continue next;
6666                            }
6667                            
6668                            int relevance = computeBaseRelevance();
6669                            relevance += computeRelevanceForResolution();
6670                            relevance += computeRelevanceForInterestingProposal();
6671                            relevance += computeRelevanceForCaseMatching(token, typeName);
6672                            relevance += computeRelevanceForExpectingType(refBinding);
6673                            relevance += computeRelevanceForQualification(isQualified);
6674                            relevance += computeRelevanceForRestrictions(accessibility);
6675                            
6676                            if(refBinding.isClass()) {
6677                                relevance += computeRelevanceForClass();
6678                                relevance += computeRelevanceForException(typeName);
6679                            } else if(refBinding.isEnum()) {
6680                                relevance += computeRelevanceForEnum();
6681                            } else if(refBinding.isInterface()) {
6682                                relevance += computeRelevanceForInterface();
6683                            }
6684                                
6685                            this.noProposal = false;
6686                            if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
6687                                CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
6688                                proposal.setDeclarationSignature(packageName);
6689                                proposal.setSignature(getSignature(refBinding));
6690                                proposal.setPackageName(packageName);
6691                                proposal.setTypeName(typeName);
6692                                proposal.setCompletion(completionName);
6693                                proposal.setFlags(refBinding.modifiers);
6694                                proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6695                                proposal.setRelevance(relevance);
6696                                proposal.setAccessibility(accessibility);
6697                                this.requestor.accept(proposal);
6698                                if(DEBUG) {
6699                                    this.printDebug(proposal);
6700                                }
6701                            }
6702                        }
6703                    }
6704                }
6705            }
6706        } else {
6707            if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
6708                if (this.assistNodeInJavadoc == 0 || (this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0) {
6709                    findKeywords(token, BASE_TYPE_NAMES, false, false);
6710                }
6711            }
6712            if(proposeType) {
6713                int l = typesFound.size();
6714                for (int i = 0; i < l; i++) {
6715                    ReferenceBinding typeFound = (ReferenceBinding) typesFound.elementAt(i);
6716                    char[] fullyQualifiedTypeName =
6717                        CharOperation.concat(
6718                                typeFound.qualifiedPackageName(),
6719                                typeFound.qualifiedSourceName(),
6720                                '.');
6721                    this.knownTypes.put(fullyQualifiedTypeName, this);
6722                }
6723                int searchFor = IJavaSearchConstants.TYPE;
6724                if(this.assistNodeIsClass) {
6725                    searchFor = IJavaSearchConstants.CLASS;
6726                } else if(this.assistNodeIsInterface) {
6727                    searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
6728                } else if(this.assistNodeIsEnum) {
6729                    searchFor = IJavaSearchConstants.ENUM;
6730                } else if(this.assistNodeIsAnnotation) {
6731                    searchFor = IJavaSearchConstants.ANNOTATION_TYPE;
6732                }
6733                this.nameEnvironment.findTypes(
6734                        token,
6735                        proposeAllMemberTypes,
6736                        this.options.camelCaseMatch,
6737                        searchFor,
6738                        this);
6739                acceptTypes(scope);
6740            }
6741            if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
6742                this.nameEnvironment.findPackages(token, this);
6743            }
6744        }
6745    }
6746
6747    private void findTypesAndSubpackages(
6748        char[] token,
6749        PackageBinding packageBinding,
6750        Scope scope) {
6751
6752        boolean proposeType =
6753            !this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
6754            ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
6755        
6756        char[] qualifiedName =
6757            CharOperation.concatWith(packageBinding.compoundName, token, '.');
6758
6759        if (token == null || token.length == 0) {
6760            int length = qualifiedName.length;
6761            System.arraycopy(
6762                qualifiedName,
6763                0,
6764                qualifiedName = new char[length + 1],
6765                0,
6766                length);
6767            qualifiedName[length] = '.';
6768        }
6769        
6770        this.qualifiedCompletionToken = qualifiedName;
6771        
6772        if (proposeType && this.unitScope != null) {
6773            int typeLength = qualifiedName.length;
6774            SourceTypeBinding[] types = this.unitScope.topLevelTypes;
6775
6776            for (int i = 0, length = types.length; i < length; i++) {
6777                SourceTypeBinding sourceType = types[i];
6778    
6779                char[] qualifiedSourceTypeName = CharOperation.concatWith(sourceType.compoundName, '.');
6780                
6781                if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue;
6782                if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue;
6783                if (typeLength > qualifiedSourceTypeName.length) continue;
6784                if (!(packageBinding == sourceType.getPackage())) continue;
6785
6786                if (!CharOperation.prefixEquals(qualifiedName, qualifiedSourceTypeName, false)
6787                        && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName))) continue;
6788                
6789                if (this.options.checkDeprecation &&
6790                        sourceType.isViewedAsDeprecated() &&
6791                        !scope.isDefinedInSameUnit(sourceType))
6792                    continue;
6793                
6794                int accessibility = IAccessRule.K_ACCESSIBLE;
6795                if(sourceType.hasRestrictedAccess()) {
6796                    AccessRestriction accessRestriction = lookupEnvironment.getAccessRestriction(sourceType);
6797                    if(accessRestriction != null) {
6798                        switch (accessRestriction.getProblemId()) {
6799                            case IProblem.ForbiddenReference:
6800                                if (this.options.checkForbiddenReference) {
6801                                    continue;
6802                                }
6803                                accessibility = IAccessRule.K_NON_ACCESSIBLE;
6804                                break;
6805                            case IProblem.DiscouragedReference:
6806                                if (this.options.checkDiscouragedReference) {
6807                                    continue;
6808                                }
6809                                accessibility = IAccessRule.K_DISCOURAGED;
6810                                break;
6811                        }
6812                    }
6813                }
6814                
6815                this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this);
6816
6817                int relevance = computeBaseRelevance();
6818                relevance += computeRelevanceForResolution();
6819                relevance += computeRelevanceForInterestingProposal();
6820                relevance += computeRelevanceForCaseMatching(qualifiedName, qualifiedSourceTypeName);
6821                relevance += computeRelevanceForExpectingType(sourceType);
6822                relevance += computeRelevanceForQualification(false);
6823                relevance += computeRelevanceForRestrictions(accessibility);
6824                
6825                if (sourceType.isAnnotationType()) {
6826                    relevance += computeRelevanceForAnnotation();
6827                } else if (sourceType.isInterface()) {
6828                    relevance += computeRelevanceForInterface();
6829                } else if (sourceType.isClass()) {
6830                    relevance += computeRelevanceForClass();
6831                    relevance += computeRelevanceForException(sourceType.sourceName);
6832                }
6833                this.noProposal = false;
6834                if(proposeType) {
6835                    char[] typeName = sourceType.sourceName();
6836                    createTypeProposal(sourceType, typeName, IAccessRule.K_ACCESSIBLE, typeName, relevance);
6837                }
6838            }
6839        }
6840        
6841        if(proposeType) {
6842            int searchFor = IJavaSearchConstants.TYPE;
6843            if(this.assistNodeIsClass) {
6844                searchFor = IJavaSearchConstants.CLASS;
6845            } else if(this.assistNodeIsInterface) {
6846                searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
6847            } else if(this.assistNodeIsEnum) {
6848                searchFor = IJavaSearchConstants.ENUM;
6849            } else if(this.assistNodeIsAnnotation) {
6850                searchFor = IJavaSearchConstants.ANNOTATION_TYPE;
6851            }
6852            this.nameEnvironment.findTypes(
6853                    qualifiedName,
6854                    false,
6855                    this.options.camelCaseMatch,
6856                    searchFor,
6857                    this);
6858            acceptTypes(scope);
6859        }
6860        if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
6861            this.nameEnvironment.findPackages(qualifiedName, this);
6862        }
6863    }
6864
6865    private void findTypesFromStaticImports(char[] token, Scope scope, boolean proposeAllMemberTypes, ObjectVector typesFound) {
6866        ImportBinding[] importBindings = scope.compilationUnitScope().imports;
6867        for (int i = 0; i < importBindings.length; i++) {
6868            ImportBinding importBinding = importBindings[i];
6869            if(importBinding.isValidBinding() && importBinding.isStatic()) {
6870                Binding binding = importBinding.resolvedImport;
6871                if(binding != null && binding.isValidBinding()) {
6872                    if(importBinding.onDemand) {
6873                        if((binding.kind() & Binding.TYPE) != 0) {
6874                            this.findMemberTypes(
6875                                    token,
6876                                    (ReferenceBinding) binding,
6877                                    scope,
6878                                    scope.enclosingSourceType(),
6879                                    true,
6880                                    false,
6881                                    true,
6882                                    true,
6883                                    proposeAllMemberTypes,
6884                                    null,
6885                                    typesFound);
6886                        }
6887                    } else {
6888                        if ((binding.kind() & Binding.TYPE) != 0) {
6889                            ReferenceBinding typeBinding = (ReferenceBinding) binding;
6890                            int typeLength = token.length;
6891                            
6892                            if (!typeBinding.isStatic()) continue;
6893                            
6894                            if (typeLength > typeBinding.sourceName.length) continue;
6895                            
6896                            if (!CharOperation.prefixEquals(token, typeBinding.sourceName, false)
6897                                    && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeBinding.sourceName))) continue;
6898                            
6899                            if (typesFound.contains(typeBinding)) continue;
6900                            
6901                            typesFound.add(typeBinding);
6902                            
6903                            if(this.assistNodeIsClass) {
6904                                if(!typeBinding.isClass()) continue;
6905                            } else if(this.assistNodeIsInterface) {
6906                                if(!typeBinding.isInterface() && !typeBinding.isAnnotationType()) continue;
6907                            } else if (this.assistNodeIsAnnotation) {
6908                                if(!typeBinding.isAnnotationType()) continue;
6909                            }
6910                            
6911                            int relevance = computeBaseRelevance();
6912                            relevance += computeRelevanceForResolution();
6913                            relevance += computeRelevanceForInterestingProposal();
6914                            relevance += computeRelevanceForCaseMatching(token, typeBinding.sourceName);
6915                            relevance += computeRelevanceForExpectingType(typeBinding);
6916                            relevance += computeRelevanceForQualification(false);
6917                            relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
6918                            
6919                            if (typeBinding.isClass()) {
6920                                relevance += computeRelevanceForClass();
6921                                relevance += computeRelevanceForException(typeBinding.sourceName);
6922                            } else if(typeBinding.isEnum()) {
6923                                relevance += computeRelevanceForEnum();
6924                            } else if(typeBinding.isInterface()) {
6925                                relevance += computeRelevanceForInterface();
6926                            }
6927                                
6928                            this.noProposal = false;
6929                            if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
6930                                CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
6931                                proposal.setDeclarationSignature(typeBinding.qualifiedPackageName());
6932                                proposal.setSignature(getSignature(typeBinding));
6933                                proposal.setPackageName(typeBinding.qualifiedPackageName());
6934                                proposal.setTypeName(typeBinding.qualifiedSourceName());
6935                                proposal.setCompletion(typeBinding.sourceName());
6936                                proposal.setFlags(typeBinding.modifiers);
6937                                proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6938                                proposal.setRelevance(relevance);
6939                                this.requestor.accept(proposal);
6940                                if(DEBUG) {
6941                                    this.printDebug(proposal);
6942                                }
6943                            }
6944                        }
6945                    }
6946                }
6947            }
6948        }
6949    }
6950    private void findVariablesAndMethods(
6951        char[] token,
6952        Scope scope,
6953        InvocationSite invocationSite,
6954        Scope invocationScope,
6955        boolean insideTypeAnnotation,
6956        boolean insideAnnotationAttribute) {
6957
6958        if (token == null)
6959            return;
6960
6961        // Should local variables hide fields from the receiver type or any of its enclosing types?
6962
// we know its an implicit field/method access... see BlockScope getBinding/getImplicitMethod
6963

6964        boolean staticsOnly = false;
6965        // need to know if we're in a static context (or inside a constructor)
6966
int tokenLength = token.length;
6967
6968        ObjectVector localsFound = new ObjectVector();
6969        ObjectVector fieldsFound = new ObjectVector();
6970        ObjectVector methodsFound = new ObjectVector();
6971
6972        Scope currentScope = scope;
6973
6974        if (!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
6975            done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
6976

6977                switch (currentScope.kind) {
6978    
6979                    case Scope.METHOD_SCOPE :
6980                        // handle the error case inside an explicit constructor call (see MethodScope>>findField)
6981
MethodScope methodScope = (MethodScope) currentScope;
6982                        staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
6983    
6984                    case Scope.BLOCK_SCOPE :
6985                        BlockScope blockScope = (BlockScope) currentScope;
6986    
6987                        next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
6988                            LocalVariableBinding local = blockScope.locals[i];
6989    
6990                            if (local == null)
6991                                break next;
6992    
6993                            if (tokenLength > local.name.length)
6994                                continue next;
6995    
6996                            if (!CharOperation.prefixEquals(token, local.name, false /* ignore case */)
6997                                    && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, local.name)))
6998                                continue next;
6999    
7000                            if (local.isSecret())
7001                                continue next;
7002    
7003                            for (int f = 0; f < localsFound.size; f++) {
7004                                LocalVariableBinding otherLocal =
7005                                    (LocalVariableBinding) localsFound.elementAt(f);
7006                                if (CharOperation.equals(otherLocal.name, local.name, true))
7007                                    continue next;
7008                            }
7009                            localsFound.add(local);
7010    
7011                            int relevance = computeBaseRelevance();
7012                            relevance += computeRelevanceForResolution();
7013                            relevance += computeRelevanceForInterestingProposal(local);
7014                            relevance += computeRelevanceForCaseMatching(token, local.name);
7015                            relevance += computeRelevanceForExpectingType(local.type);
7016                            relevance += computeRelevanceForQualification(false);
7017                            relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for local variable
7018
this.noProposal = false;
7019                            if(!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
7020                                CompletionProposal proposal = this.createProposal(CompletionProposal.LOCAL_VARIABLE_REF, this.actualCompletionPosition);
7021                                proposal.setSignature(
7022                                    local.type == null
7023                                    ? createTypeSignature(
7024                                            CharOperation.NO_CHAR,
7025                                            local.declaration.type.toString().toCharArray())
7026                                    : getSignature(local.type));
7027                                if(local.type == null) {
7028                                    //proposal.setPackageName(null);
7029
proposal.setTypeName(local.declaration.type.toString().toCharArray());
7030                                } else {
7031                                    proposal.setPackageName(local.type.qualifiedPackageName());
7032                                    proposal.setTypeName(local.type.qualifiedSourceName());
7033                                }
7034                                proposal.setName(local.name);
7035                                proposal.setCompletion(local.name);
7036                                proposal.setFlags(local.modifiers);
7037                                proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7038                                proposal.setRelevance(relevance);
7039                                this.requestor.accept(proposal);
7040                                if(DEBUG) {
7041                                    this.printDebug(proposal);
7042                                }
7043                            }
7044                        }
7045                        break;
7046    
7047                    case Scope.COMPILATION_UNIT_SCOPE :
7048                        break done1;
7049                }
7050                currentScope = currentScope.parent;
7051            }
7052        }
7053        
7054        boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
7055        boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);
7056        
7057        staticsOnly = false;
7058        currentScope = scope;
7059
7060        if(proposeField || proposeMethod) {
7061            done2 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
7062

7063                switch (currentScope.kind) {
7064                    case Scope.METHOD_SCOPE :
7065                        // handle the error case inside an explicit constructor call (see MethodScope>>findField)
7066
MethodScope methodScope = (MethodScope) currentScope;
7067                        staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
7068                        break;
7069                    case Scope.CLASS_SCOPE :
7070                        ClassScope classScope = (ClassScope) currentScope;
7071                        SourceTypeBinding enclosingType = classScope.referenceContext.binding;
7072                        /* if (tokenLength == 0) { // only search inside the type itself if no prefix was provided
7073                                            findFields(token, enclosingType.fields(), classScope, fieldsFound, staticsOnly);
7074                                            findMethods(token, enclosingType.methods(), classScope, methodsFound, staticsOnly, false);
7075                                            break done;
7076                                        } else { */

7077                        if(!insideTypeAnnotation) {
7078                            if(proposeField) {
7079                                findFields(
7080                                    token,
7081                                    enclosingType,
7082                                    classScope,
7083                                    fieldsFound,
7084                                    localsFound,
7085                                    staticsOnly,
7086                                    invocationSite,
7087                                    invocationScope,
7088                                    true,
7089                                    true,
7090                                    null,
7091                                    null,
7092                                    null,
7093                                    false);
7094                            }
7095                            if(proposeMethod && !insideAnnotationAttribute) {
7096                                findMethods(
7097                                    token,
7098                                    null,
7099                                    null,
7100                                    enclosingType,
7101                                    classScope,
7102                                    methodsFound,
7103                                    staticsOnly,
7104                                    false,
7105                                    false,
7106                                    invocationSite,
7107                                    invocationScope,
7108                                    true,
7109                                    false,
7110                                    true,
7111                                    null,
7112                                    null,
7113                                    null,
7114                                    false);
7115                            }
7116                        }
7117                        staticsOnly |= enclosingType.isStatic();
7118                        insideTypeAnnotation = false;
7119                        // }
7120
break;
7121    
7122                    case Scope.COMPILATION_UNIT_SCOPE :
7123                        break done2;
7124                }
7125                currentScope = currentScope.parent;
7126            }
7127            
7128            // search in static import
7129
ImportBinding[] importBindings = scope.compilationUnitScope().imports;
7130            for (int i = 0; i < importBindings.length; i++) {
7131                ImportBinding importBinding = importBindings[i];
7132                if(importBinding.isValidBinding() && importBinding.isStatic()) {
7133                    Binding binding = importBinding.resolvedImport;
7134                    if(binding != null && binding.isValidBinding()) {
7135                        if(importBinding.onDemand) {
7136                            if((binding.kind() & Binding.TYPE) != 0) {
7137                                if(proposeField) {
7138                                    findFields(
7139                                        token,
7140                                        (ReferenceBinding)binding,
7141                                        scope,
7142                                        fieldsFound,
7143                                        localsFound,
7144                                        true,
7145                                        invocationSite,
7146                                        invocationScope,
7147                                        true,
7148                                        false,
7149                                        null,
7150                                        null,
7151                                        null,
7152                                        false);
7153                                }
7154                                if(proposeMethod && !insideAnnotationAttribute) {
7155                                    findMethods(
7156                                        token,
7157                                        null,
7158                                        null,
7159                                        (ReferenceBinding)binding,
7160                                        scope,
7161                                        methodsFound,
7162                                        true,
7163                                        false,
7164                                        false,
7165                                        invocationSite,
7166                                        invocationScope,
7167                                        true,
7168                                        false,
7169                                        false,
7170                                        null,
7171                                        null,
7172                                        null,
7173                                        false);
7174                                }
7175                            }
7176                        } else {
7177                            if ((binding.kind() & Binding.FIELD) != 0) {
7178                                if(proposeField) {
7179                                        findFields(
7180                                                token,
7181                                                new FieldBinding[]{(FieldBinding)binding},
7182                                                scope,
7183                                                fieldsFound,
7184                                                localsFound,
7185                                                true,
7186                                                ((FieldBinding)binding).declaringClass,
7187                                                invocationSite,
7188                                                invocationScope,
7189                                                true,
7190                                                false,
7191                                                null,
7192                                                null,
7193                                                null,
7194                                                false);
7195                                }
7196                            } else if ((binding.kind() & Binding.METHOD) != 0) {
7197                                if(proposeMethod && !insideAnnotationAttribute) {
7198                                    MethodBinding methodBinding = (MethodBinding)binding;
7199                                    if(CharOperation.prefixEquals(token, methodBinding.selector))
7200                                        
7201                                    findLocalMethodsOfStaticImports(
7202                                            methodBinding.selector,
7203                                            methodBinding.declaringClass.methods(),
7204                                            scope,
7205                                            methodsFound,
7206                                            methodBinding.declaringClass,
7207                                            invocationSite);
7208                                }
7209                            }
7210                        }
7211                    }
7212                }
7213            }
7214            
7215            if (this.assistNodeInJavadoc == 0) {
7216                // search in favorites import
7217
findFieldsAndMethodsFromFavorites(
7218                        token,
7219                        scope,
7220                        invocationSite,
7221                        invocationScope,
7222                        localsFound,
7223                        fieldsFound,
7224                        methodsFound);
7225            }
7226        }
7227    }
7228    private char[][] findVariableFromUnresolvedReference(LocalDeclaration variable, BlockScope scope, final char[][] discouragedNames) {
7229        final TypeReference type = variable.type;
7230        if(type != null &&
7231                type.resolvedType != null &&
7232                type.resolvedType.problemId() == ProblemReasons.NoError){
7233            
7234            final ArrayList JavaDoc proposedNames = new ArrayList JavaDoc();
7235            
7236            UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
7237                new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
7238                    public void acceptName(char[] name) {
7239                        int relevance = computeBaseRelevance();
7240                        relevance += computeRelevanceForInterestingProposal();
7241                        relevance += computeRelevanceForCaseMatching(completionToken, name);
7242                        relevance += R_NAME_FIRST_PREFIX;
7243                        relevance += R_NAME_FIRST_SUFFIX;
7244                        relevance += R_NAME_LESS_NEW_CHARACTERS;
7245                        relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name
7246

7247                        // accept result
7248
CompletionEngine.this.noProposal = false;
7249                        if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
7250                            CompletionProposal proposal = CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition);
7251                            proposal.setSignature(getSignature(type.resolvedType));
7252                            proposal.setPackageName(type.resolvedType.qualifiedPackageName());
7253                            proposal.setTypeName(type.resolvedType.qualifiedSourceName());
7254                            proposal.setName(name);
7255                            proposal.setCompletion(name);
7256                            //proposal.setFlags(Flags.AccDefault);
7257
proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
7258                            proposal.setRelevance(relevance);
7259                            CompletionEngine.this.requestor.accept(proposal);
7260                            if(DEBUG) {
7261                                CompletionEngine.this.printDebug(proposal);
7262                            }
7263                        }
7264                        proposedNames.add(name);
7265                    }
7266                };
7267            
7268            ReferenceContext referenceContext = scope.referenceContext();
7269            if (referenceContext instanceof AbstractMethodDeclaration) {
7270                AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
7271                
7272                UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
7273                nameFinder.find(
7274                        completionToken,
7275                        md,
7276                        variable.declarationSourceEnd + 1,
7277                        discouragedNames,
7278                        nameRequestor);
7279            } else if (referenceContext instanceof TypeDeclaration) {
7280                TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
7281                FieldDeclaration[] fields = typeDeclaration.fields;
7282                if (fields != null) {
7283                    done : for (int i = 0; i < fields.length; i++) {
7284                        if (fields[i] instanceof Initializer) {
7285                            Initializer initializer = (Initializer) fields[i];
7286                            if (initializer.bodyStart <= variable.sourceStart &&
7287                                    variable.sourceStart < initializer.bodyEnd) {
7288                                UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
7289                                nameFinder.find(
7290                                        completionToken,
7291                                        initializer,
7292                                        typeDeclaration.scope,
7293                                        variable.declarationSourceEnd + 1,
7294                                        discouragedNames,
7295                                        nameRequestor);
7296                                break done;
7297                            }
7298                        }
7299                    }
7300                }
7301            }
7302            
7303            int proposedNamesCount = proposedNames.size();
7304            if (proposedNamesCount > 0) {
7305                return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
7306            }
7307        }
7308        
7309        return null;
7310    }
7311    
7312    private char[][] findUnresolvedReferenceAfter(int from, BlockScope scope, final char[][] discouragedNames) {
7313        final ArrayList JavaDoc proposedNames = new ArrayList JavaDoc();
7314        
7315        UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
7316            new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
7317                public void acceptName(char[] name) {
7318                    CompletionEngine.this.acceptUnresolvedName(name);
7319                    proposedNames.add(name);
7320                }
7321            };
7322        
7323        ReferenceContext referenceContext = scope.referenceContext();
7324        if (referenceContext instanceof AbstractMethodDeclaration) {
7325            AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
7326            
7327            UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
7328            nameFinder.findAfter(
7329                    completionToken,
7330                    md.scope,
7331                    md.scope.classScope(),
7332                    from,
7333                    md.bodyEnd,
7334                    discouragedNames,
7335                    nameRequestor);
7336        } else if (referenceContext instanceof TypeDeclaration) {
7337            TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
7338            FieldDeclaration[] fields = typeDeclaration.fields;
7339            if (fields != null) {
7340                done : for (int i = 0; i < fields.length; i++) {
7341                    if (fields[i] instanceof Initializer) {
7342                        Initializer initializer = (Initializer) fields[i];
7343                        if (initializer.block.sourceStart <= from &&
7344                                from < initializer.bodyEnd) {
7345                            UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
7346                            nameFinder.findAfter(
7347                                        completionToken,
7348                                        typeDeclaration.scope,
7349                                        typeDeclaration.scope,
7350                                        from,
7351                                        initializer.bodyEnd,
7352                                        discouragedNames,
7353                                        nameRequestor);
7354                            break done;
7355                        }
7356                    }
7357                }
7358            }
7359        }
7360        
7361        int proposedNamesCount = proposedNames.size();
7362        if (proposedNamesCount > 0) {
7363            return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
7364        }
7365        
7366        return null;
7367    }
7368    
7369    private void findUnresolvedReference(int completedNameStart, int completedNameEnd, BlockScope scope, char[][] discouragedNames) {
7370        char[][] foundNames = findUnresolvedReferenceBefore(completedNameStart - 1, completedNameEnd, scope, discouragedNames);
7371        if (foundNames != null && foundNames.length > 1) {
7372            int discouragedNamesLength = discouragedNames.length;
7373            int foundNamesLength = foundNames.length;
7374            int newLength = discouragedNamesLength + foundNamesLength;
7375            System.arraycopy(discouragedNames, 0, discouragedNames = new char[newLength][], 0, discouragedNamesLength);
7376            System.arraycopy(foundNames, 0, discouragedNames, discouragedNamesLength, foundNamesLength);
7377        }
7378        findUnresolvedReferenceAfter(completedNameEnd + 1, scope, discouragedNames);
7379    }
7380    
7381    private char[][] findUnresolvedReferenceBefore(int recordTo, int parseTo, BlockScope scope, final char[][] discouragedNames) {
7382        final ArrayList JavaDoc proposedNames = new ArrayList JavaDoc();
7383        
7384        UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
7385            new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
7386                public void acceptName(char[] name) {
7387                    CompletionEngine.this.acceptUnresolvedName(name);
7388                    proposedNames.add(name);
7389                }
7390            };
7391            
7392        BlockScope upperScope = scope;
7393        while (upperScope.enclosingMethodScope() != null) {
7394            upperScope = upperScope.enclosingMethodScope();
7395        }
7396        
7397        ReferenceContext referenceContext = upperScope.referenceContext();
7398        if (referenceContext instanceof AbstractMethodDeclaration) {
7399            AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
7400            
7401            UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
7402            nameFinder.findBefore(
7403                    completionToken,
7404                    md.scope,
7405                    md.scope.classScope(),
7406                    md.bodyStart,
7407                    recordTo,
7408                    parseTo,
7409                    discouragedNames,
7410                    nameRequestor);
7411        } else if (referenceContext instanceof TypeDeclaration) {
7412            TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
7413            
7414            
7415            done : {
7416                FieldDeclaration[] fields = typeDeclaration.fields;
7417                if (fields != null) {
7418                    for (int i = 0; i < fields.length; i++) {
7419                        if (fields[i] instanceof Initializer) {
7420                            Initializer initializer = (Initializer) fields[i];
7421                            if (initializer.block.sourceStart <= recordTo &&
7422                                    recordTo < initializer.bodyEnd) {
7423                    
7424                                UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
7425                                nameFinder.findBefore(
7426                                        completionToken,
7427                                        typeDeclaration.scope,
7428                                        typeDeclaration.scope,
7429                                        initializer.block.sourceStart,
7430                                        recordTo,
7431                                        parseTo,
7432                                        discouragedNames,
7433                                        nameRequestor);
7434                                break done;
7435                            }
7436                        }
7437                    }
7438                }
7439            }
7440        }
7441        
7442        int proposedNamesCount = proposedNames.size();
7443        if (proposedNamesCount > 0) {
7444            return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
7445        }
7446        
7447        return null;
7448    }
7449        // Helper method for private void findVariableNames(char[] name, TypeReference type )
7450
private void findVariableName(
7451        char[] token,
7452        char[] qualifiedPackageName,
7453        char[] qualifiedSourceName,
7454        char[] sourceName,
7455        final TypeBinding typeBinding,
7456        char[][] discouragedNames,
7457        final char[][] forbiddenNames,
7458        int dim,
7459        int kind,
7460        int modifiers){
7461            
7462        if(sourceName == null || sourceName.length == 0)
7463            return;
7464
7465        // compute variable name for non base type
7466
final char[] displayName;
7467        if (dim > 0){
7468            int l = qualifiedSourceName.length;
7469            displayName = new char[l+(2*dim)];
7470            System.arraycopy(qualifiedSourceName, 0, displayName, 0, l);
7471            for(int i = 0; i < dim; i++){
7472                displayName[l+(i*2)] = '[';
7473                displayName[l+(i*2)+1] = ']';
7474            }
7475        } else {
7476            displayName = qualifiedSourceName;
7477        }
7478        
7479        final char[] t = token;
7480        final char[] q = qualifiedPackageName;
7481        INamingRequestor namingRequestor = new INamingRequestor() {
7482            public void acceptNameWithPrefixAndSuffix(char[] name, boolean isFirstPrefix, boolean isFirstSuffix, int reusedCharacters) {
7483                accept(
7484                        name,
7485                        (isFirstPrefix ? R_NAME_FIRST_PREFIX : R_NAME_PREFIX) + (isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX),
7486                        reusedCharacters);
7487            }
7488
7489            public void acceptNameWithPrefix(char[] name, boolean isFirstPrefix, int reusedCharacters) {
7490                accept(name, isFirstPrefix ? R_NAME_FIRST_PREFIX : R_NAME_PREFIX, reusedCharacters);
7491            }
7492
7493            public void acceptNameWithSuffix(char[] name, boolean isFirstSuffix, int reusedCharacters) {
7494                accept(name, isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX, reusedCharacters);
7495            }
7496
7497            public void acceptNameWithoutPrefixAndSuffix(char[] name,int reusedCharacters) {
7498                accept(name, 0, reusedCharacters);
7499            }
7500            void accept(char[] name, int prefixAndSuffixRelevance, int reusedCharacters){
7501                int l = forbiddenNames == null ? 0 : forbiddenNames.length;
7502                for (int i = 0; i < l; i++) {
7503                    if (CharOperation.equals(forbiddenNames[i], name, false)) return;
7504                }
7505                
7506                if (CharOperation.prefixEquals(t, name, false)) {
7507                    int relevance = computeBaseRelevance();
7508                    relevance += computeRelevanceForInterestingProposal();
7509                    relevance += computeRelevanceForCaseMatching(t, name);
7510                    relevance += prefixAndSuffixRelevance;
7511                    if(reusedCharacters > 0) relevance += R_NAME_LESS_NEW_CHARACTERS;
7512                    relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name
7513

7514                    // accept result
7515
CompletionEngine.this.noProposal = false;
7516                    if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
7517                        CompletionProposal proposal = CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition);
7518                        proposal.setSignature(getSignature(typeBinding));
7519                        proposal.setPackageName(q);
7520                        proposal.setTypeName(displayName);
7521                        proposal.setName(name);
7522                        proposal.setCompletion(name);
7523                        //proposal.setFlags(Flags.AccDefault);
7524
proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
7525                        proposal.setRelevance(relevance);
7526                        CompletionEngine.this.requestor.accept(proposal);
7527                        if(DEBUG) {
7528                            CompletionEngine.this.printDebug(proposal);
7529                        }
7530                    }
7531                }
7532            }
7533        };
7534        
7535        switch (kind) {
7536            case FIELD :
7537                InternalNamingConventions.suggestFieldNames(
7538                    this.javaProject,
7539                    qualifiedPackageName,
7540                    qualifiedSourceName,
7541                    dim,
7542                    modifiers,
7543                    token,
7544                    discouragedNames,
7545                    namingRequestor);
7546                break;
7547            case LOCAL :
7548                InternalNamingConventions.suggestLocalVariableNames(
7549                    this.javaProject,
7550                    qualifiedPackageName,
7551                    qualifiedSourceName,
7552                    dim,
7553                    token,
7554                    discouragedNames,
7555                    namingRequestor);
7556                break;
7557            case ARGUMENT :
7558                InternalNamingConventions.suggestArgumentNames(
7559                    this.javaProject,
7560                    qualifiedPackageName,
7561                    qualifiedSourceName,
7562                    dim,
7563                    token,
7564                    discouragedNames,
7565                    namingRequestor);
7566                break;
7567        }
7568    }
7569
7570    private void findVariableNames(char[] name, TypeReference type , char[][] discouragedNames, char[][] forbiddenNames, int kind, int modifiers){
7571
7572        if(type != null &&
7573            type.resolvedType != null &&
7574            type.resolvedType.problemId() == ProblemReasons.NoError){
7575            TypeBinding tb = type.resolvedType;
7576            findVariableName(
7577                name,
7578                tb.leafComponentType().qualifiedPackageName(),
7579                tb.leafComponentType().qualifiedSourceName(),
7580                tb.leafComponentType().sourceName(),
7581                tb,
7582                discouragedNames,
7583                forbiddenNames,
7584                type.dimensions(),
7585                kind,
7586                modifiers);
7587        }/* else {
7588            char[][] typeName = type.getTypeName();
7589            findVariableName(
7590                name,
7591                NoChar,
7592                CharOperation.concatWith(typeName, '.'),
7593                typeName[typeName.length - 1],
7594                excludeNames,
7595                type.dimensions());
7596        }*/

7597    }
7598    
7599    private ImportBinding[] getFavoriteReferenceBindings(Scope scope) {
7600        if (this.favoriteReferenceBindings != null) return this.favoriteReferenceBindings;
7601        
7602        String JavaDoc[] favoriteReferences = this.requestor.getFavoriteReferences();
7603        
7604        if (favoriteReferences == null || favoriteReferences.length == 0) return null;
7605        
7606        ImportBinding[] resolvedImports = new ImportBinding[favoriteReferences.length];
7607        
7608        int count = 0;
7609        next : for (int i = 0; i < favoriteReferences.length; i++) {
7610            String JavaDoc favoriteReference = favoriteReferences[i];
7611            
7612            int length;
7613            if (favoriteReference == null || (length = favoriteReference.length()) == 0) continue next;
7614            
7615            boolean onDemand = favoriteReference.charAt(length - 1) == '*';
7616            
7617            char[][] compoundName = CharOperation.splitOn('.', favoriteReference.toCharArray());
7618            if (onDemand) {
7619                compoundName = CharOperation.subarray(compoundName, 0, compoundName.length - 1);
7620            }
7621            
7622            // remove duplicate and conflicting
7623
for (int j = 0; j < count; j++) {
7624                ImportReference f = resolvedImports[j].reference;
7625                
7626                if (CharOperation.equals(f.tokens, compoundName)) continue next;
7627                
7628                if (!onDemand && ((f.bits & ASTNode.OnDemand) == 0)) {
7629                    if (CharOperation.equals(f.tokens[f.tokens.length - 1], compoundName[compoundName.length - 1]))
7630                        continue next;
7631                }
7632            }
7633            
7634            boolean isStatic = true;
7635            
7636            ImportReference importReference =
7637                new ImportReference(
7638                        compoundName,
7639                        new long[compoundName.length],
7640                        onDemand,
7641                        isStatic ? ClassFileConstants.AccStatic : ClassFileConstants.AccDefault);
7642            
7643            Binding importBinding = this.unitScope.findImport(compoundName, isStatic, onDemand);
7644            
7645            if (!importBinding.isValidBinding()) {
7646                continue next;
7647            }
7648            
7649            if (importBinding instanceof PackageBinding) {
7650                continue next;
7651            }
7652            
7653            resolvedImports[count++] =
7654                new ImportBinding(compoundName, onDemand, importBinding, importReference);
7655        }
7656        
7657        if (resolvedImports.length > count)
7658            System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[count], 0, count);
7659        
7660        return this.favoriteReferenceBindings = resolvedImports;
7661    }
7662    
7663    public AssistParser getParser() {
7664
7665        return this.parser;
7666    }
7667    
7668    protected boolean hasPossibleAnnotationTarget(TypeBinding typeBinding, Scope scope) {
7669        if (this.targetedElement == TagBits.AnnotationForPackage) {
7670            long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
7671            if(target != 0 && (target & TagBits.AnnotationForPackage) == 0) {
7672                return false;
7673            }
7674        } else if ((this.targetedElement & TagBits.AnnotationForType) != 0) {
7675            if (scope.parent != null &&
7676                    scope.parent.parent != null &&
7677                    scope.parent.referenceContext() instanceof CompletionOnAnnotationOfType &&
7678                    scope.parent.parent instanceof CompilationUnitScope) {
7679                long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
7680                if ((this.targetedElement & TagBits.AnnotationForAnnotationType) != 0) {
7681                    if(target != 0 && (target &(TagBits.AnnotationForType | TagBits.AnnotationForAnnotationType)) == 0) {
7682                        return false;
7683                    }
7684                } else {
7685                    if(target != 0 && (target &(TagBits.AnnotationForType)) == 0) {
7686                        return false;
7687                    }
7688                }
7689            }
7690        }
7691        return true;
7692    }
7693
7694    protected void reset() {
7695
7696        super.reset();
7697        this.knownPkgs = new HashtableOfObject(10);
7698        this.knownTypes = new HashtableOfObject(10);
7699    }
7700    
7701    private void setSourceRange(int start, int end) {
7702        this.setSourceRange(start, end, true);
7703    }
7704
7705    private void setSourceRange(int start, int end, boolean emptyTokenAdjstment) {
7706        this.startPosition = start;
7707        if(emptyTokenAdjstment) {
7708            int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken;
7709            this.endPosition = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1;
7710        } else {
7711            this.endPosition = end + 1;
7712        }
7713    }
7714    private char[][] computeAlreadyDefinedName(
7715            BlockScope scope,
7716            InvocationSite invocationSite) {
7717        ArrayList JavaDoc result = new ArrayList JavaDoc();
7718        
7719        boolean staticsOnly = false;
7720
7721        Scope currentScope = scope;
7722
7723        done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
7724

7725            switch (currentScope.kind) {
7726
7727                case Scope.METHOD_SCOPE :
7728                    // handle the error case inside an explicit constructor call (see MethodScope>>findField)
7729
MethodScope methodScope = (MethodScope) currentScope;
7730                    staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
7731
7732                case Scope.BLOCK_SCOPE :
7733                    BlockScope blockScope = (BlockScope) currentScope;
7734
7735                    next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
7736                        LocalVariableBinding local = blockScope.locals[i];
7737
7738                        if (local == null)
7739                            break next;
7740
7741                        if (local.isSecret())
7742                            continue next;
7743
7744                        result.add(local.name);
7745                    }
7746                    break;
7747
7748                case Scope.CLASS_SCOPE :
7749                    ClassScope classScope = (ClassScope) currentScope;
7750                    SourceTypeBinding enclosingType = classScope.referenceContext.binding;
7751                    computeAlreadyDefinedName(
7752                            enclosingType,
7753                            classScope,
7754                            staticsOnly,
7755                            invocationSite,
7756                            result);
7757                    staticsOnly |= enclosingType.isStatic();
7758                    break;
7759                    
7760                case Scope.COMPILATION_UNIT_SCOPE :
7761                    break done1;
7762            }
7763            currentScope = currentScope.parent;
7764        }
7765        
7766        if (result.size() == 0) return CharOperation.NO_CHAR_CHAR;
7767        
7768        return (char[][])result.toArray(new char[result.size()][]);
7769    }
7770
7771    private void computeAlreadyDefinedName(
7772            SourceTypeBinding receiverType,
7773            ClassScope scope,
7774            boolean onlyStaticFields,
7775            InvocationSite invocationSite,
7776            ArrayList JavaDoc result) {
7777
7778        ReferenceBinding currentType = receiverType;
7779        ReferenceBinding[] interfacesToVisit = null;
7780        int nextPosition = 0;
7781        do {
7782            ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
7783            if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
7784                if (interfacesToVisit == null) {
7785                    interfacesToVisit = itsInterfaces;
7786                    nextPosition = interfacesToVisit.length;
7787                } else {
7788                    int itsLength = itsInterfaces.length;
7789                    if (nextPosition + itsLength >= interfacesToVisit.length)
7790                        System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
7791                    nextInterface : for (int a = 0; a < itsLength; a++) {
7792                        ReferenceBinding next = itsInterfaces[a];
7793                        for (int b = 0; b < nextPosition; b++)
7794                            if (next == interfacesToVisit[b]) continue nextInterface;
7795                        interfacesToVisit[nextPosition++] = next;
7796                    }
7797                }
7798            }
7799
7800            FieldBinding[] fields = currentType.availableFields();
7801            if(fields != null && fields.length > 0) {
7802                computeAlreadyDefinedName(
7803                    fields,
7804                    scope,
7805                    onlyStaticFields,
7806                    receiverType,
7807                    invocationSite,
7808                    result);
7809            }
7810            currentType = currentType.superclass();
7811        } while ( currentType != null);
7812
7813        if (interfacesToVisit != null) {
7814            for (int i = 0; i < nextPosition; i++) {
7815                ReferenceBinding anInterface = interfacesToVisit[i];
7816                FieldBinding[] fields = anInterface.availableFields();
7817                if(fields != null) {
7818                    computeAlreadyDefinedName(
7819                        fields,
7820                        scope,
7821                        onlyStaticFields,
7822                        receiverType,
7823                        invocationSite,
7824                        result);
7825                }
7826
7827                ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
7828                if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
7829                    int itsLength = itsInterfaces.length;
7830                    if (nextPosition + itsLength >= interfacesToVisit.length)
7831                        System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
7832                    nextInterface : for (int a = 0; a < itsLength; a++) {
7833                        ReferenceBinding next = itsInterfaces[a];
7834                        for (int b = 0; b < nextPosition; b++)
7835                            if (next == interfacesToVisit[b]) continue nextInterface;
7836                        interfacesToVisit[nextPosition++] = next;
7837                    }
7838                }
7839            }
7840        }
7841    }
7842    
7843    private void computeAlreadyDefinedName(
7844            FieldBinding[] fields,
7845            Scope scope,
7846            boolean onlyStaticFields,
7847            ReferenceBinding receiverType,
7848            InvocationSite invocationSite,
7849            ArrayList JavaDoc result) {
7850        
7851        next : for (int f = fields.length; --f >= 0;) {
7852            FieldBinding field = fields[f];
7853
7854            if (field.isSynthetic()) continue next;
7855            
7856            if (onlyStaticFields && !field.isStatic()) continue next;
7857            
7858            if (!field.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
7859
7860            result.add(field.name);
7861        }
7862    }
7863    
7864    int computeBaseRelevance(){
7865        return R_DEFAULT;
7866    }
7867    int computeRelevanceForResolution(){
7868        return computeRelevanceForResolution(true);
7869    }
7870    int computeRelevanceForResolution(boolean isResolved){
7871        if (isResolved) {
7872            return R_RESOLVED;
7873        }
7874        return 0;
7875    }
7876    private void computeExpectedTypes(ASTNode parent, ASTNode node, Scope scope){
7877        
7878        // default filter
7879
this.expectedTypesFilter = SUBTYPE;
7880        this.hasJavaLangObjectAsExpectedType = false;
7881        
7882        // find types from parent
7883
if(parent instanceof AbstractVariableDeclaration) {
7884            AbstractVariableDeclaration variable = (AbstractVariableDeclaration)parent;
7885            TypeBinding binding = variable.type.resolvedType;
7886            if(binding != null) {
7887                if(!(variable.initialization instanceof ArrayInitializer)) {
7888                    addExpectedType(binding, scope);
7889                }
7890            }
7891        } else if(parent instanceof Assignment) {
7892            TypeBinding binding = ((Assignment)parent).lhs.resolvedType;
7893            if(binding != null) {
7894                addExpectedType(binding, scope);
7895            }
7896        } else if(parent instanceof ReturnStatement) {
7897            if(scope.methodScope().referenceContext instanceof AbstractMethodDeclaration) {
7898                MethodBinding methodBinding = ((AbstractMethodDeclaration) scope.methodScope().referenceContext).binding;
7899                TypeBinding binding = methodBinding == null ? null : methodBinding.returnType;
7900                if(binding != null) {
7901                    addExpectedType(binding, scope);
7902                }
7903            }
7904        } else if(parent instanceof CastExpression) {
7905            Expression e = ((CastExpression)parent).type;
7906            TypeBinding binding = e.resolvedType;
7907            if(binding != null){
7908                addExpectedType(binding, scope);
7909                this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
7910            }
7911        } else if(parent instanceof MessageSend) {
7912            MessageSend messageSend = (MessageSend) parent;
7913
7914            if(messageSend.actualReceiverType instanceof ReferenceBinding) {
7915                ReferenceBinding binding = (ReferenceBinding)messageSend.actualReceiverType;
7916                boolean isStatic = messageSend.receiver.isTypeReference();
7917                
7918                while(binding != null) {
7919                    computeExpectedTypesForMessageSend(
7920                        binding,
7921                        messageSend.selector,
7922                        messageSend.arguments,
7923                        (ReferenceBinding)messageSend.actualReceiverType,
7924                        scope,
7925                        messageSend,
7926                        isStatic);
7927                    computeExpectedTypesForMessageSendForInterface(
7928                        binding,
7929                        messageSend.selector,
7930                        messageSend.arguments,
7931                        (ReferenceBinding)messageSend.actualReceiverType,
7932                        scope,
7933                        messageSend,
7934                        isStatic);
7935                    binding = binding.superclass();
7936                }
7937            }
7938        } else if(parent instanceof AllocationExpression) {
7939            AllocationExpression allocationExpression = (AllocationExpression) parent;
7940            
7941            ReferenceBinding binding = (ReferenceBinding)allocationExpression.type.resolvedType;
7942
7943            if(binding != null) {
7944                computeExpectedTypesForAllocationExpression(
7945                    binding,
7946                    allocationExpression.arguments,
7947                    scope,
7948                    allocationExpression);
7949            }
7950        } else if(parent instanceof OperatorExpression) {
7951            int operator = (parent.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT;
7952            if(parent instanceof ConditionalExpression) {
7953                // for future use
7954
} else if(parent instanceof InstanceOfExpression) {
7955                InstanceOfExpression e = (InstanceOfExpression) parent;
7956                TypeBinding binding = e.expression.resolvedType;
7957                if(binding != null){
7958                    addExpectedType(binding, scope);
7959                    this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
7960                }
7961            } else if(parent instanceof BinaryExpression) {
7962                switch(operator) {
7963                    case OperatorIds.PLUS :
7964                        addExpectedType(TypeBinding.SHORT, scope);
7965                        addExpectedType(TypeBinding.INT, scope);
7966                        addExpectedType(TypeBinding.LONG, scope);
7967                        addExpectedType(TypeBinding.FLOAT, scope);
7968                        addExpectedType(TypeBinding.DOUBLE, scope);
7969                        addExpectedType(TypeBinding.CHAR, scope);
7970                        addExpectedType(TypeBinding.BYTE, scope);
7971                        addExpectedType(scope.getJavaLangString(), scope);
7972                        break;
7973                    case OperatorIds.AND_AND :
7974                    case OperatorIds.OR_OR :
7975                    case OperatorIds.XOR :
7976                        addExpectedType(TypeBinding.BOOLEAN, scope);
7977                        break;
7978                    default :
7979                        addExpectedType(TypeBinding.SHORT, scope);
7980                        addExpectedType(TypeBinding.INT, scope);
7981                        addExpectedType(TypeBinding.LONG, scope);
7982                        addExpectedType(TypeBinding.FLOAT, scope);
7983                        addExpectedType(TypeBinding.DOUBLE, scope);
7984                        addExpectedType(TypeBinding.CHAR, scope);
7985                        addExpectedType(TypeBinding.BYTE, scope);
7986                        break;
7987                }
7988                BinaryExpression binaryExpression = (BinaryExpression) parent;
7989                if(operator == OperatorIds.LESS) {
7990                    if(binaryExpression.left instanceof SingleNameReference){
7991                        SingleNameReference name = (SingleNameReference) binaryExpression.left;
7992                        Binding b = scope.getBinding(name.token, Binding.VARIABLE | Binding.TYPE, name, false);
7993                        if(b instanceof ReferenceBinding) {
7994                            TypeVariableBinding[] typeVariableBindings =((ReferenceBinding)b).typeVariables();
7995                            if(typeVariableBindings != null && typeVariableBindings.length > 0) {
7996                                addExpectedType(typeVariableBindings[0].firstBound, scope);
7997                            }
7998                            
7999                        }
8000                    }
8001                }
8002            } else if(parent instanceof UnaryExpression) {
8003                switch(operator) {
8004                    case OperatorIds.NOT :
8005                        addExpectedType(TypeBinding.BOOLEAN, scope);
8006                        break;
8007                    case OperatorIds.TWIDDLE :
8008                        addExpectedType(TypeBinding.SHORT, scope);
8009                        addExpectedType(TypeBinding.INT, scope);
8010                        addExpectedType(TypeBinding.LONG, scope);
8011                        addExpectedType(TypeBinding.CHAR, scope);
8012                        addExpectedType(TypeBinding.BYTE, scope);
8013                        break;
8014                    case OperatorIds.PLUS :
8015                    case OperatorIds.MINUS :
8016                    case OperatorIds.PLUS_PLUS :
8017                    case OperatorIds.MINUS_MINUS :
8018                        addExpectedType(TypeBinding.SHORT, scope);
8019                        addExpectedType(TypeBinding.INT, scope);
8020                        addExpectedType(TypeBinding.LONG, scope);
8021                        addExpectedType(TypeBinding.FLOAT, scope);
8022                        addExpectedType(TypeBinding.DOUBLE, scope);
8023                        addExpectedType(TypeBinding.CHAR, scope);
8024                        addExpectedType(TypeBinding.BYTE, scope);
8025                        break;
8026                }
8027            }
8028        } else if(parent instanceof ArrayReference) {
8029            addExpectedType(TypeBinding.SHORT, scope);
8030            addExpectedType(TypeBinding.INT, scope);
8031            addExpectedType(TypeBinding.LONG, scope);
8032        } else if(parent instanceof ParameterizedSingleTypeReference) {
8033            ParameterizedSingleTypeReference ref = (ParameterizedSingleTypeReference) parent;
8034            TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
8035            int length = ref.typeArguments == null ? 0 : ref.typeArguments.length;
8036            if(typeVariables != null && typeVariables.length >= length) {
8037                int index = length - 1;
8038                while(index > -1 && ref.typeArguments[index] != node) index--;
8039                
8040                TypeBinding bound = typeVariables[index].firstBound;
8041                addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
8042            }
8043        } else if(parent instanceof ParameterizedQualifiedTypeReference) {
8044            ParameterizedQualifiedTypeReference ref = (ParameterizedQualifiedTypeReference) parent;
8045            TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
8046            TypeReference[][] arguments = ref.typeArguments;
8047            if(typeVariables != null) {
8048                int iLength = arguments == null ? 0 : arguments.length;
8049                done: for (int i = 0; i < iLength; i++) {
8050                    int jLength = arguments[i] == null ? 0 : arguments[i].length;
8051                    for (int j = 0; j < jLength; j++) {
8052                        if(arguments[i][j] == node && typeVariables.length > j) {
8053                            TypeBinding bound = typeVariables[j].firstBound;
8054                            addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
8055                            break done;
8056                        }
8057                    }
8058                }
8059            }
8060        } else if(parent instanceof MemberValuePair) {
8061            MemberValuePair memberValuePair = (MemberValuePair) parent;
8062            if(memberValuePair.binding != null) {
8063                addExpectedType(memberValuePair.binding.returnType, scope);
8064            }
8065        } else if (parent instanceof NormalAnnotation) {
8066            NormalAnnotation annotation = (NormalAnnotation) parent;
8067            MemberValuePair[] memberValuePairs = annotation.memberValuePairs();
8068            if(memberValuePairs == null || memberValuePairs.length == 0) {
8069                if(annotation.resolvedType instanceof ReferenceBinding) {
8070                    MethodBinding[] methodBindings =
8071                        ((ReferenceBinding)annotation.resolvedType).availableMethods();
8072                    if (methodBindings != null &&
8073                            methodBindings.length > 0 &&
8074                            CharOperation.equals(methodBindings[0].selector, VALUE)) {
8075                        boolean canBeSingleMemberAnnotation = true;
8076                        done : for (int i = 1; i < methodBindings.length; i++) {
8077                            if((methodBindings[i].modifiers & ClassFileConstants.AccAnnotationDefault) == 0) {
8078                                canBeSingleMemberAnnotation = false;
8079                                break done;
8080                            }
8081                        }
8082                        if (canBeSingleMemberAnnotation) {
8083                            this.assistNodeCanBeSingleMemberAnnotation = canBeSingleMemberAnnotation;
8084                            addExpectedType(methodBindings[0].returnType, scope);
8085                        }
8086                    }
8087                }
8088            }
8089        } else if (parent instanceof TryStatement) {
8090            boolean isException = false;
8091            if (node instanceof CompletionOnSingleTypeReference) {
8092                isException = ((CompletionOnSingleTypeReference)node).isException();
8093            } else if (node instanceof CompletionOnQualifiedTypeReference) {
8094                isException = ((CompletionOnQualifiedTypeReference)node).isException();
8095            } else if (node instanceof CompletionOnParameterizedQualifiedTypeReference) {
8096                isException = ((CompletionOnParameterizedQualifiedTypeReference)node).isException();
8097            }
8098            if (isException) {
8099                ThrownExceptionFinder thrownExceptionFinder = new ThrownExceptionFinder();
8100                ReferenceBinding[] bindings = thrownExceptionFinder.find((TryStatement) parent, (BlockScope)scope);
8101                if (bindings != null && bindings.length > 0) {
8102                    for (int i = 0; i < bindings.length; i++) {
8103                        addExpectedType(bindings[i], scope);
8104                    }
8105                    this.expectedTypesFilter = SUPERTYPE;
8106                }
8107            }
8108            
8109        // Expected types for javadoc
8110
} else if (parent instanceof Javadoc) {
8111            if (scope.kind == Scope.METHOD_SCOPE) {
8112                MethodScope methodScope = (MethodScope) scope;
8113                AbstractMethodDeclaration methodDecl = methodScope.referenceMethod();
8114                if (methodDecl != null && methodDecl.binding != null) {
8115                    ReferenceBinding[] exceptions = methodDecl.binding.thrownExceptions;
8116                    if (exceptions != null) {
8117                        for (int i = 0; i < exceptions.length; i++) {
8118                            addExpectedType(exceptions[i], scope);
8119                        }
8120                    }
8121                }
8122            }
8123        }
8124        
8125        if(this.expectedTypesPtr + 1 != this.expectedTypes.length) {
8126            System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[this.expectedTypesPtr + 1], 0, this.expectedTypesPtr + 1);
8127        }
8128    }
8129    
8130    private void computeExpectedTypesForAllocationExpression(
8131        ReferenceBinding binding,
8132        Expression[] arguments,
8133        Scope scope,
8134        InvocationSite invocationSite) {
8135            
8136        MethodBinding[] methods = binding.availableMethods();
8137        nextMethod : for (int i = 0; i < methods.length; i++) {
8138            MethodBinding method = methods[i];
8139            
8140            if (!method.isConstructor()) continue nextMethod;
8141            
8142            if (method.isSynthetic()) continue nextMethod;
8143            
8144            if (this.options.checkVisibility && !method.canBeSeenBy(invocationSite, scope)) continue nextMethod;
8145            
8146            TypeBinding[] parameters = method.parameters;
8147            if(parameters.length < arguments.length)
8148                continue nextMethod;
8149                
8150            int length = arguments.length - 1;
8151            
8152            for (int j = 0; j < length; j++) {
8153                Expression argument = arguments[j];
8154                TypeBinding argType = argument.resolvedType;
8155                if(argType != null && !argType.isCompatibleWith(parameters[j]))
8156                    continue nextMethod;
8157            }
8158            
8159            TypeBinding expectedType = method.parameters[arguments.length - 1];
8160            if(expectedType != null) {
8161                addExpectedType(expectedType, scope);
8162            }
8163        }
8164    }
8165    
8166    private void computeExpectedTypesForMessageSendForInterface(
8167        ReferenceBinding binding,
8168        char[] selector,
8169        Expression[] arguments,
8170        ReferenceBinding receiverType,
8171        Scope scope,
8172        InvocationSite invocationSite,
8173        boolean isStatic) {
8174
8175        ReferenceBinding[] itsInterfaces = binding.superInterfaces();
8176        if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
8177            ReferenceBinding[] interfacesToVisit = itsInterfaces;
8178            int nextPosition = interfacesToVisit.length;
8179
8180            for (int i = 0; i < nextPosition; i++) {
8181                ReferenceBinding currentType = interfacesToVisit[i];
8182                computeExpectedTypesForMessageSend(
8183                    currentType,
8184                    selector,
8185                    arguments,
8186                    receiverType,
8187                    scope,
8188                    invocationSite,
8189                    isStatic);
8190
8191                if ((itsInterfaces = currentType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
8192                    int itsLength = itsInterfaces.length;
8193                    if (nextPosition + itsLength >= interfacesToVisit.length)
8194                        System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
8195                    nextInterface : for (int a = 0; a < itsLength; a++) {
8196                        ReferenceBinding next = itsInterfaces[a];
8197                        for (int b = 0; b < nextPosition; b++)
8198                            if (next == interfacesToVisit[b]) continue nextInterface;
8199                        interfacesToVisit[nextPosition++] = next;
8200                    }
8201                }
8202            }
8203        }
8204    }
8205    
8206    private void computeExpectedTypesForMessageSend(
8207        ReferenceBinding binding,
8208        char[] selector,
8209        Expression[] arguments,
8210        ReferenceBinding receiverType,
8211        Scope scope,
8212        InvocationSite invocationSite,
8213        boolean isStatic) {
8214            
8215        MethodBinding[] methods = binding.availableMethods();
8216        nextMethod : for (int i = 0; i < methods.length; i++) {
8217            MethodBinding method = methods[i];
8218            
8219            if (method.isSynthetic()) continue nextMethod;
8220
8221            if (method.isDefaultAbstract()) continue nextMethod;
8222
8223            if (method.isConstructor()) continue nextMethod;
8224
8225            if (isStatic && !method.isStatic()) continue nextMethod;
8226            
8227            if (this.options.checkVisibility && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue nextMethod;
8228            
8229            if(!CharOperation.equals(method.selector, selector)) continue nextMethod;
8230            
8231            TypeBinding[] parameters = method.parameters;
8232            if(parameters.length < arguments.length)
8233                continue nextMethod;
8234                
8235            int length = arguments.length - 1;
8236            
8237            for (int j = 0; j < length; j++) {
8238                Expression argument = arguments[j];
8239                TypeBinding argType = argument.resolvedType;
8240                if(argType != null && !argType.isCompatibleWith(parameters[j]))
8241                    continue nextMethod;
8242            }
8243                
8244            TypeBinding expectedType = method.parameters[arguments.length - 1];
8245            if(expectedType != null) {
8246                addExpectedType(expectedType, scope);
8247            }
8248        }
8249    }
8250    private void addExpectedType(TypeBinding type, Scope scope){
8251        if (type == null || !type.isValidBinding()) return;
8252
8253        int length = this.expectedTypes.length;
8254        if (++this.expectedTypesPtr >= length)
8255            System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[length * 2], 0, length);
8256        this.expectedTypes[this.expectedTypesPtr] = type;
8257        
8258        if(type == scope.getJavaLangObject()) {
8259            this.hasJavaLangObjectAsExpectedType = true;
8260        }
8261    }
8262    private void addForbiddenBindings(Binding binding){
8263        if (binding == null) return;
8264
8265        int length = this.forbbidenBindings.length;
8266        if (++this.forbbidenBindingsPtr >= length)
8267            System.arraycopy(this.forbbidenBindings, 0, this.forbbidenBindings = new Binding[length * 2], 0, length);
8268        this.forbbidenBindings[this.forbbidenBindingsPtr] = binding;
8269    }
8270    private void addUninterestingBindings(Binding binding){
8271        if (binding == null) return;
8272
8273        int length = this.uninterestingBindings.length;
8274        if (++this.uninterestingBindingsPtr >= length)
8275            System.arraycopy(this.uninterestingBindings, 0, this.uninterestingBindings = new Binding[length * 2], 0, length);
8276        this.uninterestingBindings[this.uninterestingBindingsPtr] = binding;
8277    }
8278
8279    private Scope computeForbiddenBindings(ASTNode astNode, ASTNode astNodeParent, Scope scope) {
8280        this.forbbidenBindingsFilter = NONE;
8281        if(scope instanceof ClassScope) {
8282            TypeDeclaration typeDeclaration = ((ClassScope)scope).referenceContext;
8283            if(typeDeclaration.superclass == astNode) {
8284                this.addForbiddenBindings(typeDeclaration.binding);
8285                return scope.parent;
8286            }
8287            TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
8288            int length = superInterfaces == null ? 0 : superInterfaces.length;
8289            for (int i = 0; i < length; i++) {
8290                if(superInterfaces[i] == astNode) {
8291                    this.addForbiddenBindings(typeDeclaration.binding);
8292                    return scope.parent;
8293                }
8294            }
8295        } else {
8296            if (astNodeParent != null && astNodeParent instanceof TryStatement) {
8297                boolean isException = false;
8298                if (astNode instanceof CompletionOnSingleTypeReference) {
8299                    isException = ((CompletionOnSingleTypeReference)astNode).isException();
8300                } else if (astNode instanceof CompletionOnQualifiedTypeReference) {
8301                    isException = ((CompletionOnQualifiedTypeReference)astNode).isException();
8302                } else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
8303                    isException = ((CompletionOnParameterizedQualifiedTypeReference)astNode).isException();
8304                }
8305                if (isException) {
8306                    Argument[] catchArguments = ((TryStatement) astNodeParent).catchArguments;
8307                    int length = catchArguments == null ? 0 : catchArguments.length;
8308                    for (int i = 0; i < length; i++) {
8309                        TypeBinding caughtException = catchArguments[i].type.resolvedType;
8310                        if (caughtException != null) {
8311                            this.addForbiddenBindings(caughtException);
8312                            this.knownTypes.put(CharOperation.concat(caughtException.qualifiedPackageName(), caughtException.qualifiedSourceName(), '.'), this);
8313                        }
8314                    }
8315                    this.forbbidenBindingsFilter = SUBTYPE;
8316                }
8317            }
8318        }
8319// else if(scope instanceof MethodScope) {
8320
// MethodScope methodScope = (MethodScope) scope;
8321
// if(methodScope.insideTypeAnnotation) {
8322
// return methodScope.parent.parent;
8323
// }
8324
// }
8325
return scope;
8326    }
8327    private char[] computePrefix(SourceTypeBinding declarationType, SourceTypeBinding invocationType, boolean isStatic){
8328        
8329        StringBuffer JavaDoc completion = new StringBuffer JavaDoc(10);
8330
8331        if (isStatic) {
8332            completion.append(declarationType.sourceName());
8333            
8334        } else if (declarationType == invocationType) {
8335            completion.append(THIS);
8336            
8337        } else {
8338            
8339            if (!declarationType.isNestedType()) {
8340                
8341                completion.append(declarationType.sourceName());
8342                completion.append('.');
8343                completion.append(THIS);
8344
8345            } else if (!declarationType.isAnonymousType()) {
8346                
8347                completion.append(declarationType.sourceName());
8348                completion.append('.');
8349                completion.append(THIS);
8350                
8351            }
8352        }
8353        
8354        return completion.toString().toCharArray();
8355    }
8356    
8357    private void proposeNewMethod(char[] token, ReferenceBinding reference) {
8358        if(!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
8359            int relevance = computeBaseRelevance();
8360            relevance += computeRelevanceForResolution();
8361            relevance += computeRelevanceForInterestingProposal();
8362            relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for new method
8363

8364            CompletionProposal proposal = this.createProposal(CompletionProposal.POTENTIAL_METHOD_DECLARATION, this.actualCompletionPosition);
8365            proposal.setDeclarationSignature(getSignature(reference));
8366            proposal.setSignature(
8367                    createMethodSignature(
8368                            CharOperation.NO_CHAR_CHAR,
8369                            CharOperation.NO_CHAR_CHAR,
8370                            CharOperation.NO_CHAR,
8371                            VOID));
8372            proposal.setDeclarationPackageName(reference.qualifiedPackageName());
8373            proposal.setDeclarationTypeName(reference.qualifiedSourceName());
8374            
8375            //proposal.setPackageName(null);
8376
proposal.setTypeName(VOID);
8377            proposal.setName(token);
8378            //proposal.setParameterPackageNames(null);
8379
//proposal.setParameterTypeNames(null);
8380
//proposal.setPackageName(null);
8381
proposal.setCompletion(token);
8382            proposal.setFlags(Flags.AccPublic);
8383            proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
8384            proposal.setRelevance(relevance);
8385            this.requestor.accept(proposal);
8386            if(DEBUG) {
8387                this.printDebug(proposal);
8388            }
8389        }
8390    }
8391    private boolean isForbidden(Binding binding) {
8392        for (int i = 0; i <= this.forbbidenBindingsPtr; i++) {
8393            if(this.forbbidenBindings[i] == binding) {
8394                return true;
8395            }
8396            if((this.forbbidenBindingsFilter & SUBTYPE) != 0) {
8397                if (binding instanceof TypeBinding &&
8398                        this.forbbidenBindings[i] instanceof TypeBinding &&
8399                        ((TypeBinding)binding).isCompatibleWith((TypeBinding)this.forbbidenBindings[i])) {
8400                    return true;
8401                }
8402            }
8403        }
8404        return false;
8405    }
8406    private boolean isValidParent(ASTNode parent, ASTNode node, Scope scope){
8407        
8408        if(parent instanceof ParameterizedSingleTypeReference) {
8409            ParameterizedSingleTypeReference ref = (ParameterizedSingleTypeReference) parent;
8410            TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
8411            int length = ref.typeArguments == null ? 0 : ref.typeArguments.length;
8412            int nodeIndex = -1;
8413            for(int i = length - 1 ; i > -1 ; i--) {
8414                if(node == ref.typeArguments[i]) {
8415                    nodeIndex = i;
8416                    break;
8417                }
8418            }
8419            if(nodeIndex > -1 && (typeVariables == null || typeVariables.length < nodeIndex + 1)) {
8420                TypeBinding[] typeBindings = new TypeBinding[nodeIndex + 1];
8421                for(int i = 0; i < nodeIndex; i++) {
8422                    typeBindings[i] = ref.typeArguments[i].resolvedType;
8423                }
8424                typeBindings[nodeIndex] = scope.getJavaLangObject();
8425                if(typeVariables == null || typeVariables.length == 0) {
8426                    scope.problemReporter().nonGenericTypeCannotBeParameterized(ref, ref.resolvedType, typeBindings);
8427                } else {
8428                    scope.problemReporter().incorrectArityForParameterizedType(ref, ref.resolvedType, typeBindings);
8429                }
8430                return false;
8431            }
8432        } else if(parent instanceof ParameterizedQualifiedTypeReference) {
8433            ParameterizedQualifiedTypeReference ref = (ParameterizedQualifiedTypeReference) parent;
8434            TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
8435            TypeReference[][] arguments = ref.typeArguments;
8436            int iLength = arguments == null ? 0 : arguments.length;
8437            for (int i = 0; i < iLength; i++) {
8438                int jLength = arguments[i] == null ? 0 : arguments[i].length;
8439                for (int j = 0; j < jLength; j++) {
8440                    if(arguments[i][j] == node && (typeVariables == null || typeVariables.length <= j)) {
8441                        TypeBinding[] typeBindings = new TypeBinding[j + 1];
8442                        for(int k = 0; k < j; k++) {
8443                            typeBindings[k] = ref.typeArguments[i][k].resolvedType;
8444                        }
8445                        typeBindings[j] = scope.getJavaLangObject();
8446                        if(typeVariables == null || typeVariables.length == 0) {
8447                            scope.problemReporter().nonGenericTypeCannotBeParameterized(ref, ref.resolvedType, typeBindings);
8448                        } else {
8449                            scope.problemReporter().incorrectArityForParameterizedType(ref, ref.resolvedType, typeBindings);
8450                        }
8451                        return false;
8452                    }
8453                }
8454            }
8455        }
8456        return true;
8457    }
8458    
8459    public static char[] createNonGenericTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) {
8460        return Signature.createCharArrayTypeSignature(
8461                CharOperation.concat(
8462                        qualifiedPackageName,
8463                        CharOperation.replaceOnCopy(qualifiedTypeName, '.', '$'), '.'), true);
8464    }
8465    public static char[] createTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) {
8466        char[] name = new char[qualifiedTypeName.length];
8467        System.arraycopy(qualifiedTypeName, 0, name, 0, qualifiedTypeName.length);
8468        
8469        int depth = 0;
8470        int length = name.length;
8471        for (int i = length -1; i >= 0; i--) {
8472            switch (name[i]) {
8473                case '.':
8474                    if (depth == 0 && name[i - 1] != '>') {
8475                        name[i] = '$';
8476                    }
8477                    break;
8478                case '<':
8479                    depth--;
8480                    break;
8481                case '>':
8482                    depth++;
8483                    break;
8484            }
8485        }
8486        return Signature.createCharArrayTypeSignature(
8487                CharOperation.concat(
8488                        qualifiedPackageName,
8489                        name, '.'), true);
8490    }
8491    
8492    public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnPackagename, char[] returnTypeName) {
8493        char[] returnTypeSignature =
8494            returnTypeName == null || returnTypeName.length == 0
8495            ? Signature.createCharArrayTypeSignature(VOID, true)
8496            : Signature.createCharArrayTypeSignature(
8497                    CharOperation.concat(
8498                            returnPackagename,
8499                            CharOperation.replaceOnCopy(returnTypeName, '.', '$'), '.'), true);
8500        
8501        return createMethodSignature(
8502                parameterPackageNames,
8503                parameterTypeNames,
8504                returnTypeSignature);
8505    }
8506    
8507    public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnTypeSignature) {
8508        char[][] parameterTypeSignature = new char[parameterTypeNames.length][];
8509        for (int i = 0; i < parameterTypeSignature.length; i++) {
8510            parameterTypeSignature[i] =
8511                Signature.createCharArrayTypeSignature(
8512                        CharOperation.concat(
8513                                parameterPackageNames[i],
8514                                CharOperation.replaceOnCopy(parameterTypeNames[i], '.', '$'), '.'), true);
8515        }
8516            
8517        return Signature.createMethodSignature(
8518                parameterTypeSignature,
8519                returnTypeSignature);
8520    }
8521    
8522    protected CompletionProposal createProposal(int kind, int completionOffset) {
8523        CompletionProposal proposal = CompletionProposal.create(kind, completionOffset - this.offset);
8524        proposal.nameLookup = this.nameEnvironment.nameLookup;
8525        proposal.completionEngine = this;
8526        return proposal;
8527    }
8528
8529    /*
8530     * Create a completion proposal for a type.
8531     */

8532    private void createTypeProposal(char[] packageName, char[] typeName, int modifiers, int accessibility, char[] completionName, int relevance) {
8533
8534        // Create standard type proposal
8535
if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
8536            CompletionProposal proposal = CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
8537            proposal.nameLookup = this.nameEnvironment.nameLookup;
8538            proposal.completionEngine = this;
8539            proposal.setDeclarationSignature(packageName);
8540            proposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
8541            proposal.setPackageName(packageName);
8542            proposal.setTypeName(typeName);
8543            proposal.setCompletion(completionName);
8544            proposal.setFlags(modifiers);
8545            proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
8546            proposal.setRelevance(relevance);
8547            proposal.setAccessibility(accessibility);
8548            this.requestor.accept(proposal);
8549            if(DEBUG) {
8550                this.printDebug(proposal);
8551            }
8552        }
8553        
8554        // Create javadoc text proposal if necessary
8555
if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
8556            char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
8557            CompletionProposal proposal = CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
8558            proposal.nameLookup = this.nameEnvironment.nameLookup;
8559            proposal.completionEngine = this;
8560            proposal.setDeclarationSignature(packageName);
8561            proposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
8562            proposal.setPackageName(packageName);
8563            proposal.setTypeName(typeName);
8564            proposal.setCompletion(javadocCompletion);
8565            proposal.setFlags(modifiers);
8566            int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
8567            proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
8568            proposal.setRelevance(relevance+R_INLINE_TAG);
8569            proposal.setAccessibility(accessibility);
8570            this.requestor.accept(proposal);
8571            if(DEBUG) {
8572                this.printDebug(proposal);
8573            }
8574        }
8575    }
8576
8577    /*
8578     * Create a completion proposal for a member type.
8579     */

8580    private void createTypeProposal(ReferenceBinding refBinding, char[] typeName, int accessibility, char[] completionName, int relevance) {
8581
8582        // Create standard type proposal
8583
if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
8584            CompletionProposal proposal = CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
8585            proposal.nameLookup = this.nameEnvironment.nameLookup;
8586            proposal.completionEngine = this;
8587            proposal.setDeclarationSignature(refBinding.qualifiedPackageName());
8588            proposal.setSignature(getSignature(refBinding));
8589            proposal.setPackageName(refBinding.qualifiedPackageName());
8590            proposal.setTypeName(typeName);
8591            proposal.setCompletion(completionName);
8592            proposal.setFlags(refBinding.modifiers);
8593            proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
8594            proposal.setRelevance(relevance);
8595            this.requestor.accept(proposal);
8596            if(DEBUG) {
8597                this.printDebug(proposal);
8598            }
8599        }
8600        
8601        // Create javadoc text proposal if necessary
8602
if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
8603            char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
8604            CompletionProposal proposal = CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
8605            proposal.nameLookup = this.nameEnvironment.nameLookup;
8606            proposal.completionEngine = this;
8607            proposal.setDeclarationSignature(refBinding.qualifiedPackageName());
8608            proposal.setSignature(getSignature(refBinding));
8609            proposal.setPackageName(refBinding.qualifiedPackageName());
8610            proposal.setTypeName(typeName);
8611            proposal.setCompletion(javadocCompletion);
8612            proposal.setFlags(refBinding.modifiers);
8613            int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
8614            proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
8615            proposal.setRelevance(relevance+R_INLINE_TAG);
8616            this.requestor.accept(proposal);
8617            if(DEBUG) {
8618                this.printDebug(proposal);
8619            }
8620        }
8621    }
8622
8623    /*
8624     * Create a completion proposal for a member type.
8625     */

8626    private void createTypeParameterProposal(TypeParameter typeParameter, int relevance) {
8627        char[] completionName = typeParameter.name;
8628
8629        // Create standard type proposal
8630
if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
8631            CompletionProposal proposal = CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
8632            proposal.nameLookup = this.nameEnvironment.nameLookup;
8633            proposal.completionEngine = this;
8634            proposal.setSignature(getSignature(typeParameter.binding));
8635            proposal.setTypeName(completionName);
8636            proposal.setCompletion(completionName);
8637            proposal.setFlags(typeParameter.modifiers);
8638            proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
8639            proposal.setRelevance(relevance);
8640            this.requestor.accept(proposal);
8641            if(DEBUG) {
8642                this.printDebug(proposal);
8643            }
8644        }
8645        
8646        // Create javadoc text proposal if necessary
8647
if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
8648            char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
8649            CompletionProposal proposal = CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
8650            proposal.nameLookup = this.nameEnvironment.nameLookup;
8651            proposal.completionEngine = this;
8652            proposal.setSignature(getSignature(typeParameter.binding));
8653            proposal.setTypeName(javadocCompletion);
8654            proposal.setCompletion(javadocCompletion);
8655            proposal.setFlags(typeParameter.modifiers);
8656            proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
8657            proposal.setRelevance(relevance+R_INLINE_TAG);
8658            this.requestor.accept(proposal);
8659            if(DEBUG) {
8660                this.printDebug(proposal);
8661            }
8662        }
8663    }
8664
8665    /**
8666     * Returns completion string inserted inside a specified inline tag.
8667     * @param completionName
8668     * @return char[] Completion text inclunding specified inline tag
8669     */

8670    private char[] inlineTagCompletion(char[] completionName, char[] inlineTag) {
8671        int tagLength= inlineTag.length;
8672        int completionLength = completionName.length;
8673        int inlineLength = 2+tagLength+1+completionLength+1;
8674        char[] inlineCompletion = new char[inlineLength];
8675        inlineCompletion[0] = '{';
8676        inlineCompletion[1] = '@';
8677        System.arraycopy(inlineTag, 0, inlineCompletion, 2, tagLength);
8678        inlineCompletion[tagLength+2] = ' ';
8679        System.arraycopy(completionName, 0, inlineCompletion, tagLength+3, completionLength);
8680        // do not add space at end of inline tag (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=121026)
8681
//inlineCompletion[inlineLength-2] = ' ';
8682
inlineCompletion[inlineLength-1] = '}';
8683        return inlineCompletion;
8684    }
8685
8686    protected void printDebug(CategorizedProblem error) {
8687        if(CompletionEngine.DEBUG) {
8688            System.out.print("COMPLETION - completionFailure("); //$NON-NLS-1$
8689
System.out.print(error);
8690            System.out.println(")"); //$NON-NLS-1$
8691
}
8692    }
8693    
8694    private void printDebugTab(int tab, StringBuffer JavaDoc buffer) {
8695        for (int i = 0; i < tab; i++) {
8696            buffer.append('\t');
8697        }
8698    }
8699    
8700    protected void printDebug(CompletionProposal proposal){
8701        StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
8702        printDebug(proposal, 0, buffer);
8703        System.out.println(buffer.toString());
8704    }
8705    private void printDebug(CompletionProposal proposal, int tab, StringBuffer JavaDoc buffer){
8706        printDebugTab(tab, buffer);
8707        buffer.append("COMPLETION - "); //$NON-NLS-1$
8708
switch(proposal.getKind()) {
8709            case CompletionProposal.ANONYMOUS_CLASS_DECLARATION :
8710                buffer.append("ANONYMOUS_CLASS_DECLARATION"); //$NON-NLS-1$
8711
break;
8712            case CompletionProposal.FIELD_REF :
8713                buffer.append("FIELD_REF"); //$NON-NLS-1$
8714
break;
8715            case CompletionProposal.KEYWORD :
8716                buffer.append("KEYWORD"); //$NON-NLS-1$
8717
break;
8718            case CompletionProposal.LABEL_REF :
8719                buffer.append("LABEL_REF"); //$NON-NLS-1$
8720
break;
8721            case CompletionProposal.LOCAL_VARIABLE_REF :
8722                buffer.append("LOCAL_VARIABLE_REF"); //$NON-NLS-1$
8723
break;
8724            case CompletionProposal.METHOD_DECLARATION :
8725                buffer.append("METHOD_DECLARATION"); //$NON-NLS-1$
8726
break;
8727            case CompletionProposal.METHOD_REF :
8728                buffer.append("METHOD_REF"); //$NON-NLS-1$
8729
break;
8730            case CompletionProposal.PACKAGE_REF :
8731                buffer.append("PACKAGE_REF"); //$NON-NLS-1$
8732
break;
8733            case CompletionProposal.TYPE_REF :
8734                buffer.append("TYPE_REF"); //$NON-NLS-1$
8735
break;
8736            case CompletionProposal.VARIABLE_DECLARATION :
8737                buffer.append("VARIABLE_DECLARATION"); //$NON-NLS-1$
8738
break;
8739            case CompletionProposal.POTENTIAL_METHOD_DECLARATION :
8740                buffer.append("POTENTIAL_METHOD_DECLARATION"); //$NON-NLS-1$
8741
break;
8742            case CompletionProposal.METHOD_NAME_REFERENCE :
8743                buffer.append("METHOD_NAME_REFERENCE"); //$NON-NLS-1$
8744
break;
8745            case CompletionProposal.ANNOTATION_ATTRIBUTE_REF :
8746                buffer.append("ANNOTATION_ATTRIBUT_REF"); //$NON-NLS-1$
8747
break;
8748            case CompletionProposal.FIELD_IMPORT :
8749                buffer.append("FIELD_IMPORT"); //$NON-NLS-1$
8750
break;
8751            case CompletionProposal.METHOD_IMPORT :
8752                buffer.append("METHOD_IMPORT"); //$NON-NLS-1$
8753
break;
8754            case CompletionProposal.TYPE_IMPORT :
8755                buffer.append("TYPE_IMPORT"); //$NON-NLS-1$
8756
break;
8757            default :
8758                buffer.append("PROPOSAL"); //$NON-NLS-1$
8759
break;
8760                
8761        }
8762        
8763        buffer.append("{\n");//$NON-NLS-1$
8764
printDebugTab(tab, buffer);
8765        buffer.append("\tCompletion[").append(proposal.getCompletion() == null ? "null".toCharArray() : proposal.getCompletion()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
8766
printDebugTab(tab, buffer);
8767        buffer.append("\tDeclarationSignature[").append(proposal.getDeclarationSignature() == null ? "null".toCharArray() : proposal.getDeclarationSignature()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
8768
printDebugTab(tab, buffer);
8769        buffer.append("\tDeclarationKey[").append(proposal.getDeclarationKey() == null ? "null".toCharArray() : proposal.getDeclarationKey()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
8770
printDebugTab(tab, buffer);
8771        buffer.append("\tSignature[").append(proposal.getSignature() == null ? "null".toCharArray() : proposal.getSignature()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
8772
printDebugTab(tab, buffer);
8773        buffer.append("\tKey[").append(proposal.getKey() == null ? "null".toCharArray() : proposal.getKey()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
8774
printDebugTab(tab, buffer);
8775        buffer.append("\tName[").append(proposal.getName() == null ? "null".toCharArray() : proposal.getName()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
8776

8777        printDebugTab(tab, buffer);
8778        buffer.append("\tFlags[");//$NON-NLS-1$
8779
int flags = proposal.getFlags();
8780        buffer.append(Flags.toString(flags));
8781        if((flags & Flags.AccInterface) != 0) buffer.append("interface ");//$NON-NLS-1$
8782
if((flags & Flags.AccEnum) != 0) buffer.append("enum ");//$NON-NLS-1$
8783
buffer.append("]\n"); //$NON-NLS-1$
8784

8785        CompletionProposal[] proposals = proposal.getRequiredProposals();
8786        if(proposals != null) {
8787            printDebugTab(tab, buffer);
8788            buffer.append("\tRequiredProposals[");//$NON-NLS-1$
8789
for (int i = 0; i < proposals.length; i++) {
8790                buffer.append("\n"); //$NON-NLS-1$
8791
printDebug(proposals[i], tab + 2, buffer);
8792            }
8793            printDebugTab(tab, buffer);
8794            buffer.append("\n\t]\n"); //$NON-NLS-1$
8795
}
8796        
8797        printDebugTab(tab, buffer);
8798        buffer.append("\tCompletionLocation[").append(proposal.getCompletionLocation()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$
8799
int start = proposal.getReplaceStart();
8800        int end = proposal.getReplaceEnd();
8801        printDebugTab(tab, buffer);
8802        buffer.append("\tReplaceStart[").append(start).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
8803
buffer.append("-ReplaceEnd[").append(end).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$
8804
if (this.source != null) {
8805            printDebugTab(tab, buffer);
8806            buffer.append("\tReplacedText[").append(this.source, start, end-start).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$
8807
}
8808        printDebugTab(tab, buffer);
8809        buffer.append("\tTokenStart[").append(proposal.getTokenStart()).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
8810
buffer.append("-TokenEnd[").append(proposal.getTokenEnd()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$
8811
printDebugTab(tab, buffer);
8812        buffer.append("\tRelevance[").append(proposal.getRelevance()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$
8813

8814        printDebugTab(tab, buffer);
8815        buffer.append("}\n");//$NON-NLS-1$
8816
}
8817    
8818    private char[][] substituteMethodTypeParameterNames(TypeVariableBinding[] typeVariables, char[][] excludedNames) {
8819        char[][] substituedParameterNames = new char[typeVariables.length][];
8820        
8821        for (int i = 0; i < substituedParameterNames.length; i++) {
8822            substituedParameterNames[i] = typeVariables[i].sourceName;
8823        }
8824        
8825        boolean foundConflicts = false;
8826        
8827        nextTypeParameter : for (int i = 0; i < typeVariables.length; i++) {
8828            TypeVariableBinding typeVariableBinding = typeVariables[i];
8829            char[] methodParameterName = typeVariableBinding.sourceName;
8830            
8831            for (int j = 0; j < excludedNames.length; j++) {
8832                char[] typeParameterName = excludedNames[j];
8833                if(CharOperation.equals(typeParameterName, methodParameterName, false)) {
8834                    char[] substitution;
8835                    if(methodParameterName.length == 1) {
8836                        if(ScannerHelper.isUpperCase(methodParameterName[0])) {
8837                            substitution = substituteMethodTypeParameterName(methodParameterName[0], 'A', 'Z', excludedNames, substituedParameterNames);
8838                        } else {
8839                            substitution = substituteMethodTypeParameterName(methodParameterName[0], 'a', 'z', excludedNames, substituedParameterNames);
8840                        }
8841                    } else {
8842                        substitution = substituteMethodTypeParameterName(methodParameterName, excludedNames, substituedParameterNames);
8843                    }
8844                    substituedParameterNames[i] = substitution;
8845                    
8846                    foundConflicts = true;
8847                    continue nextTypeParameter;
8848                }
8849            }
8850        }
8851        
8852        if(foundConflicts) return substituedParameterNames;
8853        return null;
8854    }
8855    
8856    private char[] substituteMethodTypeParameterName(char firstName, char startChar, char endChar, char[][] excludedNames, char[][] otherParameterNames) {
8857        char name = firstName;
8858        next : while (true) {
8859            for (int i = 0 ; i < excludedNames.length ; i++){
8860                if(excludedNames[i].length == 1 && ScannerHelper.toLowerCase(excludedNames[i][0]) == ScannerHelper.toLowerCase(name)) {
8861                    name++;
8862                    if(name > endChar)
8863                        name = startChar;
8864                    if(name == firstName)
8865                        return substituteMethodTypeParameterName(new char[]{firstName}, excludedNames, otherParameterNames);
8866                    continue next;
8867                }
8868            }
8869            
8870            for (int i = 0; i < otherParameterNames.length; i++) {
8871                if(otherParameterNames[i].length == 1 && ScannerHelper.toLowerCase(otherParameterNames[i][0]) == ScannerHelper.toLowerCase(name)) {
8872                    name++;
8873                    if(name > endChar)
8874                        name = startChar;
8875                    if(name == firstName)
8876                        return substituteMethodTypeParameterName(new char[]{firstName}, excludedNames, otherParameterNames);
8877                    continue next;
8878                }
8879            }
8880            break next;
8881        }
8882        return new char[]{name};
8883    }
8884    
8885    private char[] substituteMethodTypeParameterName(char[] firstName, char[][] excludedNames, char[][] otherParameterNames) {
8886        char[] name = firstName;
8887        int count = 2;
8888        next : while(true) {
8889            for(int k = 0 ; k < excludedNames.length ; k++){
8890                if(CharOperation.equals(name, excludedNames[k], false)) {
8891                    name = CharOperation.concat(firstName, String.valueOf(count++).toCharArray());
8892                    continue next;
8893                }
8894            }
8895            for (int i = 0; i < otherParameterNames.length; i++) {
8896                if(CharOperation.equals(name, otherParameterNames[i], false)) {
8897                    name = CharOperation.concat(firstName, String.valueOf(count++).toCharArray());
8898                    continue next;
8899                }
8900            }
8901            break next;
8902        }
8903        return name;
8904    }
8905}
Popular Tags