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,