+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v0.5
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- ******************************************************************************/
-package net.sourceforge.phpdt.internal.codeassist;
-
-import java.util.Locale;
-import java.util.Map;
-
-import net.sourceforge.phpdt.core.ICompletionRequestor;
-import net.sourceforge.phpdt.core.compiler.IProblem;
-import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
-import net.sourceforge.phpdt.core.compiler.InvalidInputException;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionNodeFound;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnArgumentName;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnClassLiteralAccess;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnClassReference;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnExceptionReference;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnExplicitConstructorCall;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnFieldName;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnFieldType;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnImportReference;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnInterfaceReference;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnLocalName;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnMemberAccess;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnMessageSend;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnMethodName;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnMethodReturnType;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnPackageReference;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnQualifiedAllocationExpression;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnQualifiedClassReference;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnQualifiedExceptionReference;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnQualifiedInterfaceReference;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnQualifiedNameReference;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnQualifiedTypeReference;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnSingleNameReference;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionOnSingleTypeReference;
-import net.sourceforge.phpdt.internal.codeassist.complete.CompletionParser;
-import net.sourceforge.phpdt.internal.codeassist.complete.InvalidCursorLocation;
-import net.sourceforge.phpdt.internal.codeassist.impl.AssistParser;
-import net.sourceforge.phpdt.internal.codeassist.impl.Engine;
-import net.sourceforge.phpdt.internal.compiler.CompilationResult;
-import net.sourceforge.phpdt.internal.compiler.DefaultErrorHandlingPolicies;
-import net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration;
-import net.sourceforge.phpdt.internal.compiler.ast.AbstractVariableDeclaration;
-import net.sourceforge.phpdt.internal.compiler.ast.Argument;
-import net.sourceforge.phpdt.internal.compiler.ast.Assignment;
-import net.sourceforge.phpdt.internal.compiler.ast.AstNode;
-import net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration;
-import net.sourceforge.phpdt.internal.compiler.ast.Expression;
-import net.sourceforge.phpdt.internal.compiler.ast.ImportReference;
-import net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration;
-import net.sourceforge.phpdt.internal.compiler.ast.ReturnStatement;
-import net.sourceforge.phpdt.internal.compiler.ast.SingleTypeReference;
-import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration;
-import net.sourceforge.phpdt.internal.compiler.ast.TypeReference;
-import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit;
-import net.sourceforge.phpdt.internal.compiler.env.IConstants;
-import net.sourceforge.phpdt.internal.compiler.env.ISourceMethod;
-import net.sourceforge.phpdt.internal.compiler.env.ISourceType;
-import net.sourceforge.phpdt.internal.compiler.env.NameEnvironmentAnswer;
-import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext;
-import net.sourceforge.phpdt.internal.compiler.lookup.BaseTypes;
-import net.sourceforge.phpdt.internal.compiler.lookup.Binding;
-import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope;
-import net.sourceforge.phpdt.internal.compiler.lookup.ClassScope;
-import net.sourceforge.phpdt.internal.compiler.lookup.CompilerModifiers;
-import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding;
-import net.sourceforge.phpdt.internal.compiler.lookup.InvocationSite;
-import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding;
-import net.sourceforge.phpdt.internal.compiler.lookup.LookupEnvironment;
-import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding;
-import net.sourceforge.phpdt.internal.compiler.lookup.MethodScope;
-import net.sourceforge.phpdt.internal.compiler.lookup.PackageBinding;
-import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding;
-import net.sourceforge.phpdt.internal.compiler.lookup.Scope;
-import net.sourceforge.phpdt.internal.compiler.lookup.SourceTypeBinding;
-import net.sourceforge.phpdt.internal.compiler.lookup.TagBits;
-import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding;
-import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants;
-import net.sourceforge.phpdt.internal.compiler.lookup.VariableBinding;
-import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
-import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation;
-import net.sourceforge.phpdt.internal.compiler.problem.DefaultProblemFactory;
-import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
-import net.sourceforge.phpdt.internal.compiler.util.CharOperation;
-import net.sourceforge.phpdt.internal.compiler.util.HashtableOfObject;
-import net.sourceforge.phpdt.internal.compiler.util.ObjectVector;
-
-/**
- * This class is the entry point for source completions.
- * It contains two public APIs used to call CodeAssist on a given source with
- * a given environment, assisting position and storage (and possibly options).
- */
-public final class CompletionEngine
- extends Engine
- implements ISearchRequestor, TypeConstants , ITerminalSymbols , RelevanceConstants {
-
- public static boolean DEBUG = false;
-
- private final static char[] ERROR_PATTERN = "*error*".toCharArray(); //$NON-NLS-1$
- private final static char[] EXCEPTION_PATTERN = "*exception*".toCharArray(); //$NON-NLS-1$
- private final static char[] SEMICOLON = new char[] { ';' };
- TypeBinding[] expectedTypes;
-
- boolean assistNodeIsClass;
- boolean assistNodeIsException;
- boolean assistNodeIsInterface;
-
- CompletionParser parser;
- ICompletionRequestor requestor;
- ProblemReporter problemReporter;
- char[] source;
- char[] token;
- boolean resolvingImports = false;
- boolean insideQualifiedReference = false;
- int startPosition, actualCompletionPosition, endPosition, offset;
- HashtableOfObject knownPkgs = new HashtableOfObject(10);
- HashtableOfObject knownTypes = new HashtableOfObject(10);
- Scanner nameScanner;
-
- /*
- static final char[][] mainDeclarations =
- new char[][] {
- "package".toCharArray(),
- "import".toCharArray(),
- "abstract".toCharArray(),
- "final".toCharArray(),
- "public".toCharArray(),
- "class".toCharArray(),
- "interface".toCharArray()};
-
- static final char[][] modifiers = // may want field, method, type & member type modifiers
- new char[][] {
- "abstract".toCharArray(),
- "final".toCharArray(),
- "native".toCharArray(),
- "public".toCharArray(),
- "protected".toCharArray(),
- "private".toCharArray(),
- "static".toCharArray(),
- "strictfp".toCharArray(),
- "synchronized".toCharArray(),
- "transient".toCharArray(),
- "volatile".toCharArray()};
- */
- static final char[][] baseTypes = new char[][] {
- "boolean".toCharArray(), //$NON-NLS-1$
- "byte".toCharArray(), //$NON-NLS-1$
- "char".toCharArray(), //$NON-NLS-1$
- "double".toCharArray(), //$NON-NLS-1$
- "float".toCharArray(), //$NON-NLS-1$
- "int".toCharArray(), //$NON-NLS-1$
- "long".toCharArray(), //$NON-NLS-1$
- "short".toCharArray(), //$NON-NLS-1$
- "void".toCharArray(), //$NON-NLS-1$
- };
-
- static final char[] classField = "class".toCharArray(); //$NON-NLS-1$
- static final char[] lengthField = "length".toCharArray(); //$NON-NLS-1$
- static final char[] THIS = "this".toCharArray(); //$NON-NLS-1$
- static final char[] THROWS = "throws".toCharArray(); //$NON-NLS-1$
-
- static InvocationSite FakeInvocationSite = new InvocationSite(){
- public boolean isSuperAccess(){ return false; }
- public boolean isTypeAccess(){ return false; }
- public void setActualReceiverType(ReferenceBinding receiverType) {}
- public void setDepth(int depth){}
- public void setFieldIndex(int depth){}
- };
-
- /**
- * The CompletionEngine is responsible for computing source completions.
- *
- * It requires a searchable name environment, which supports some
- * specific search APIs, and a requestor to feed back the results to a UI.
- *
- * @param nameEnvironment net.sourceforge.phpdt.internal.codeassist.ISearchableNameEnvironment
- * used to resolve type/package references and search for types/packages
- * based on partial names.
- *
- * @param requestor net.sourceforge.phpdt.internal.codeassist.ICompletionRequestor
- * since the engine might produce answers of various forms, the engine
- * is associated with a requestor able to accept all possible completions.
- *
- * @param settings java.util.Map
- * set of options used to configure the code assist engine.
- */
- public CompletionEngine(
- ISearchableNameEnvironment nameEnvironment,
- ICompletionRequestor requestor,
- Map settings) {
-
- super(settings);
- this.requestor = requestor;
- this.nameEnvironment = nameEnvironment;
-
- problemReporter = new ProblemReporter(
- DefaultErrorHandlingPolicies.proceedWithAllProblems(),
- this.compilerOptions,
- new DefaultProblemFactory(Locale.getDefault()) {
- public void record(IProblem problem, CompilationResult unitResult, ReferenceContext referenceContext) {
- if (problem.isError() && (problem.getID() & IProblem.Syntax) != 0) {
- CompletionEngine.this.requestor.acceptError(problem);
- }
- }
- });
- this.parser =
- new CompletionParser(problemReporter, this.compilerOptions.assertMode);
- this.lookupEnvironment =
- new LookupEnvironment(this, this.compilerOptions, problemReporter, nameEnvironment);
- this.nameScanner =
- new Scanner(false, false, false, this.compilerOptions.assertMode);
- }
-
- /**
- * One result of the search consists of a new class.
- *
- * NOTE - All package and type names are presented in their readable form:
- * Package names are in the form "a.b.c".
- * Nested type names are in the qualified form "A.M".
- * The default package is represented by an empty array.
- */
- public void acceptClass(char[] packageName, char[] className, int modifiers) {
-
- char[] fullyQualifiedName = CharOperation.concat(packageName, className, '.');
- char[] completionName = fullyQualifiedName;
-
- if (this.knownTypes.containsKey(completionName)) return;
-
- this.knownTypes.put(completionName, this);
-
- int relevance = R_DEFAULT;
- if (resolvingImports) {
- completionName = CharOperation.concat(completionName, SEMICOLON);
- relevance += computeRelevanceForCaseMatching(token, fullyQualifiedName);
- } else {
- if (!insideQualifiedReference) {
- if (mustQualifyType(packageName, className)) {
- if (packageName == null || packageName.length == 0)
- if (unitScope != null && unitScope.fPackage.compoundName != NoCharChar)
- return; // ignore types from the default package from outside it
- } else {
- completionName = className;
- }
- }
- relevance += computeRelevanceForCaseMatching(token, className);
- relevance += computeRelevanceForExpectingType(packageName, className);
- relevance += computeRelevanceForClass();
- relevance += computeRelevanceForException(className);
- }
-
- requestor.acceptClass(
- packageName,
- className,
- completionName,
- modifiers,
- startPosition - offset,
- endPosition - offset,
- relevance);
- }
-
- /**
- * One result of the search consists of a new interface.
- *
- * NOTE - All package and type names are presented in their readable form:
- * Package names are in the form "a.b.c".
- * Nested type names are in the qualified form "A.I".
- * The default package is represented by an empty array.
- */
- public void acceptInterface(
- char[] packageName,
- char[] interfaceName,
- int modifiers) {
-
- char[] fullyQualifiedName = CharOperation.concat(packageName, interfaceName, '.');
- char[] completionName = fullyQualifiedName;
-
- if (this.knownTypes.containsKey(completionName)) return;
-
- this.knownTypes.put(completionName, this);
-
- int relevance = R_DEFAULT;
- if (resolvingImports) {
- completionName = CharOperation.concat(completionName, new char[] { ';' });
- relevance += computeRelevanceForCaseMatching(token, fullyQualifiedName);
- } else {
- if (!insideQualifiedReference) {
- if (mustQualifyType(packageName, interfaceName)) {
- if (packageName == null || packageName.length == 0)
- if (unitScope != null && unitScope.fPackage.compoundName != NoCharChar)
- return; // ignore types from the default package from outside it
- } else {
- completionName = interfaceName;
- }
- }
- relevance += computeRelevanceForCaseMatching(token, interfaceName);
- relevance += computeRelevanceForExpectingType(packageName, interfaceName);
- relevance += computeRelevanceForInterface();
- }
-
- requestor.acceptInterface(
- packageName,
- interfaceName,
- completionName,
- modifiers,
- startPosition - offset,
- endPosition - offset,
- relevance);
- }
-
- /**
- * One result of the search consists of a new package.
- *
- * NOTE - All package names are presented in their readable form:
- * Package names are in the form "a.b.c".
- * The default package is represented by an empty array.
- */
- public void acceptPackage(char[] packageName) {
-
- if (this.knownPkgs.containsKey(packageName)) return;
-
- this.knownPkgs.put(packageName, this);
-
- int relevance = R_DEFAULT;
- relevance += computeRelevanceForCaseMatching(token, packageName);
-
- requestor.acceptPackage(
- packageName,
- resolvingImports
- ? CharOperation.concat(packageName, new char[] { '.', '*', ';' })
- : packageName,
- startPosition - offset,
- endPosition - offset,
- relevance);
- }
-
- /**
- * One result of the search consists of a new type.
- *
- * NOTE - All package and type names are presented in their readable form:
- * Package names are in the form "a.b.c".
- * Nested type names are in the qualified form "A.M".
- * The default package is represented by an empty array.
- */
- public void acceptType(char[] packageName, char[] typeName) {
-
- char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
- char[] completionName = fullyQualifiedName;
-
- if (this.knownTypes.containsKey(completionName)) return;
-
- this.knownTypes.put(completionName, this);
-
- int relevance = R_DEFAULT;
- if (resolvingImports) {
- completionName = CharOperation.concat(completionName, new char[] { ';' });
- relevance += computeRelevanceForCaseMatching(token, fullyQualifiedName);
- } else {
- if (!insideQualifiedReference) {
- if (mustQualifyType(packageName, typeName)) {
- if (packageName == null || packageName.length == 0)
- if (unitScope != null && unitScope.fPackage.compoundName != NoCharChar)
- return; // ignore types from the default package from outside it
- } else {
- completionName = typeName;
- }
- }
- relevance += computeRelevanceForCaseMatching(token, typeName);
- relevance += computeRelevanceForExpectingType(packageName, typeName);
- }
-
- requestor.acceptType(
- packageName,
- typeName,
- completionName,
- startPosition - offset,
- endPosition - offset,
- relevance);
- }
-
- private void complete(AstNode astNode, Binding qualifiedBinding, Scope scope) {
-
- setSourceRange(astNode.sourceStart, astNode.sourceEnd);
-
- if(parser.assistNodeParent != null) {
- computeExpectedTypes(parser.assistNodeParent, scope);
- }
-
- // defaults... some nodes will change these
- if (astNode instanceof CompletionOnFieldType) {
-
- CompletionOnFieldType field = (CompletionOnFieldType) astNode;
- CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) field.type;
- token = type.token;
- setSourceRange(type.sourceStart, type.sourceEnd);
- // findKeywords(token, modifiers, scope); // could be the start of a field, method or member type
- findTypesAndPackages(token, scope);
-
- if(!field.isLocalVariable && field.modifiers == CompilerModifiers.AccDefault) {
- findMethods(token,null,scope.enclosingSourceType(),scope,new ObjectVector(),false,false,true,null,null,false);
- }
- } else {
- if(astNode instanceof CompletionOnMethodReturnType) {
-
- CompletionOnMethodReturnType method = (CompletionOnMethodReturnType) astNode;
- SingleTypeReference type = (CompletionOnSingleTypeReference) method.returnType;
- token = type.token;
- setSourceRange(type.sourceStart, type.sourceEnd);
- findTypesAndPackages(token, scope);
-
- if(method.modifiers == CompilerModifiers.AccDefault) {
- findMethods(token,null,scope.enclosingSourceType(),scope,new ObjectVector(),false,false,true,null,null,false);
- }
- } else {
-
- if (astNode instanceof CompletionOnSingleNameReference) {
-
- token = ((CompletionOnSingleNameReference) astNode).token;
- findVariablesAndMethods(
- token,
- scope,
- (CompletionOnSingleNameReference) astNode,
- scope);
- // can be the start of a qualified type name
- findTypesAndPackages(token, scope);
-
- } else {
-
- if (astNode instanceof CompletionOnSingleTypeReference) {
-
- token = ((CompletionOnSingleTypeReference) astNode).token;
-
- assistNodeIsClass = astNode instanceof CompletionOnClassReference;
- assistNodeIsException = astNode instanceof CompletionOnExceptionReference;
- assistNodeIsInterface = astNode instanceof CompletionOnInterfaceReference;
-
- // can be the start of a qualified type name
- if (qualifiedBinding == null) {
- findTypesAndPackages(token, scope);
- } else {
- findMemberTypes(
- token,
- (ReferenceBinding) qualifiedBinding,
- scope,
- scope.enclosingSourceType());
- }
- } else {
-
- if (astNode instanceof CompletionOnQualifiedNameReference) {
-
- insideQualifiedReference = true;
- CompletionOnQualifiedNameReference ref =
- (CompletionOnQualifiedNameReference) astNode;
- token = ref.completionIdentifier;
- long completionPosition = ref.sourcePositions[ref.sourcePositions.length - 1];
-
- if (qualifiedBinding instanceof VariableBinding) {
-
- setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
- TypeBinding receiverType = ((VariableBinding) qualifiedBinding).type;
- if (receiverType != null) {
- findFieldsAndMethods(token, receiverType, scope, ref, scope,false);
- }
-
- } else {
-
- if (qualifiedBinding instanceof ReferenceBinding) {
-
- ReferenceBinding receiverType = (ReferenceBinding) qualifiedBinding;
- setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
-
- findMemberTypes(token, receiverType, scope, scope.enclosingSourceType());
-
- findClassField(token, (TypeBinding) qualifiedBinding, scope);
-
- findFields(
- token,
- receiverType,
- scope,
- new ObjectVector(),
- new ObjectVector(),
- true,
- ref,
- scope,
- false);
-
- findMethods(
- token,
- null,
- receiverType,
- scope,
- new ObjectVector(),
- true,
- false,
- false,
- ref,
- scope,
- false);
-
- } else {
-
- if (qualifiedBinding instanceof PackageBinding) {
-
- setSourceRange(astNode.sourceStart, (int) completionPosition);
- // replace to the end of the completion identifier
- findTypesAndSubpackages(token, (PackageBinding) qualifiedBinding);
- }
- }
- }
-
- } else {
-
- if (astNode instanceof CompletionOnQualifiedTypeReference) {
-
- insideQualifiedReference = true;
-
- assistNodeIsClass = astNode instanceof CompletionOnQualifiedClassReference;
- assistNodeIsException = astNode instanceof CompletionOnQualifiedExceptionReference;
- assistNodeIsInterface = astNode instanceof CompletionOnQualifiedInterfaceReference;
-
- CompletionOnQualifiedTypeReference ref =
- (CompletionOnQualifiedTypeReference) astNode;
- token = ref.completionIdentifier;
- long completionPosition = ref.sourcePositions[ref.tokens.length];
-
- // get the source positions of the completion identifier
- if (qualifiedBinding instanceof ReferenceBinding) {
-
- setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
- findMemberTypes(
- token,
- (ReferenceBinding) qualifiedBinding,
- scope,
- scope.enclosingSourceType());
-
- } else {
-
- if (qualifiedBinding instanceof PackageBinding) {
-
- setSourceRange(astNode.sourceStart, (int) completionPosition);
- // replace to the end of the completion identifier
- findTypesAndSubpackages(token, (PackageBinding) qualifiedBinding);
- }
- }
-
- } else {
-
- if (astNode instanceof CompletionOnMemberAccess) {
-
- CompletionOnMemberAccess access = (CompletionOnMemberAccess) astNode;
- long completionPosition = access.nameSourcePosition;
- setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
-
- token = access.token;
-
- findFieldsAndMethods(
- token,
- (TypeBinding) qualifiedBinding,
- scope,
- access,
- scope,
- false);
-
- } else {
-
- if (astNode instanceof CompletionOnMessageSend) {
-
- CompletionOnMessageSend messageSend = (CompletionOnMessageSend) astNode;
- TypeBinding[] argTypes =
- computeTypes(messageSend.arguments, (BlockScope) scope);
- token = messageSend.selector;
- if (qualifiedBinding == null) {
-
- findImplicitMessageSends(token, argTypes, scope, messageSend, scope);
- } else {
-
- findMethods(
- token,
- argTypes,
- (ReferenceBinding) qualifiedBinding,
- scope,
- new ObjectVector(),
- false,
- true,
- false,
- messageSend,
- scope,
- false);
- }
-
- } else {
-
- if (astNode instanceof CompletionOnExplicitConstructorCall) {
-
- CompletionOnExplicitConstructorCall constructorCall =
- (CompletionOnExplicitConstructorCall) astNode;
- TypeBinding[] argTypes =
- computeTypes(constructorCall.arguments, (BlockScope) scope);
- findConstructors(
- (ReferenceBinding) qualifiedBinding,
- argTypes,
- scope,
- constructorCall,
- false);
-
- } else {
-
- if (astNode instanceof CompletionOnQualifiedAllocationExpression) {
-
- CompletionOnQualifiedAllocationExpression allocExpression =
- (CompletionOnQualifiedAllocationExpression) astNode;
- TypeBinding[] argTypes =
- computeTypes(allocExpression.arguments, (BlockScope) scope);
-
- ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
- if(ref.isClass()) {
- if(!ref.isAbstract()) {
- findConstructors(
- ref,
- argTypes,
- scope,
- allocExpression,
- false);
- }
- }
- if(!ref.isFinal()){
- findAnonymousType(
- ref,
- argTypes,
- scope,
- allocExpression);
- }
-
- } else {
-
- if (astNode instanceof CompletionOnClassLiteralAccess) {
- CompletionOnClassLiteralAccess access = (CompletionOnClassLiteralAccess) astNode;
- setSourceRange(access.classStart, access.sourceEnd);
-
- token = access.completionIdentifier;
-
- findClassField(token, (TypeBinding) qualifiedBinding, scope);
- } else {
- if(astNode instanceof CompletionOnMethodName) {
- CompletionOnMethodName method = (CompletionOnMethodName) astNode;
-
- setSourceRange(method.sourceStart, method.selectorEnd);
-
- FieldBinding[] fields = scope.enclosingSourceType().fields();
- char[][] excludeNames = new char[fields.length][];
- for(int i = 0 ; i < fields.length ; i++){
- excludeNames[i] = fields[i].name;
- }
-
- token = method.selector;
-
- findVariableNames(token, method.returnType, excludeNames);
- } else {
- if (astNode instanceof CompletionOnFieldName) {
- CompletionOnFieldName field = (CompletionOnFieldName) astNode;
-
- FieldBinding[] fields = scope.enclosingSourceType().fields();
- char[][] excludeNames = new char[fields.length][];
- for(int i = 0 ; i < fields.length ; i++){
- excludeNames[i] = fields[i].name;
- }
-
- token = field.realName;
-
- findVariableNames(field.realName, field.type, excludeNames);
- } else {
- if (astNode instanceof CompletionOnLocalName ||
- astNode instanceof CompletionOnArgumentName){
- LocalDeclaration variable = (LocalDeclaration) astNode;
-
- LocalVariableBinding[] locals = ((BlockScope)scope).locals;
- char[][] excludeNames = new char[locals.length][];
- int localCount = 0;
- for(int i = 0 ; i < locals.length ; i++){
- if(locals[i] != null) {
- excludeNames[localCount++] = locals[i].name;
- }
- }
- System.arraycopy(excludeNames, 0, excludeNames = new char[localCount][], 0, localCount);
-
- if(variable instanceof CompletionOnLocalName){
- token = ((CompletionOnLocalName) variable).realName;
- } else {
- token = ((CompletionOnArgumentName) variable).realName;
- }
- findVariableNames(token, variable.type, excludeNames);
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
-
-// public void complete(IType type, char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
-// TypeConverter converter = new TypeConverter();
-//
-// IType topLevelType = type;
-// while(topLevelType.getDeclaringType() != null) {
-// topLevelType = topLevelType.getDeclaringType();
-// }
-//
-// CompilationResult compilationResult = new CompilationResult((topLevelType.getElementName() + ".java").toCharArray(), 1, 1, this.compilerOptions.maxProblemsPerUnit); //$NON-NLS-1$
-//
-// CompilationUnitDeclaration compilationUnit = new CompilationUnitDeclaration(problemReporter, compilationResult, 0);
-//
-// try {
-// TypeDeclaration typeDeclaration = converter.buildTypeDeclaration(type, compilationUnit, compilationResult, problemReporter);
-//
-// if(typeDeclaration != null) {
-// // build AST from snippet
-// Initializer fakeInitializer = parseSnippeInitializer(snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic);
-//
-// // merge AST
-// FieldDeclaration[] oldFields = typeDeclaration.fields;
-// FieldDeclaration[] newFields = new FieldDeclaration[oldFields.length + 1];
-// System.arraycopy(oldFields, 0, newFields, 0, oldFields.length);
-// newFields[oldFields.length] = fakeInitializer;
-// typeDeclaration.fields = newFields;
-//
-// if(DEBUG) {
-// System.out.println("SNIPPET COMPLETION AST :"); //$NON-NLS-1$
-// System.out.println(compilationUnit.toString());
-// }
-//
-// if (compilationUnit.types != null) {
-// try {
-// lookupEnvironment.buildTypeBindings(compilationUnit);
-//
-// if ((unitScope = compilationUnit.scope) != null) {
-// lookupEnvironment.completeTypeBindings(compilationUnit, true);
-// compilationUnit.scope.faultInTypes();
-// compilationUnit.resolve();
-// }
-// } catch (CompletionNodeFound e) {
-// // completionNodeFound = true;
-// if (e.astNode != null) {
-// // if null then we found a problem in the completion node
-// complete(e.astNode, e.qualifiedBinding, e.scope);
-// }
-// }
-// }
-// }
-// } catch(JavaModelException e) {
-// // Do nothing
-// }
-// }
-
-// private Initializer parseSnippeInitializer(char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
-// StringBuffer prefix = new StringBuffer();
-// prefix.append("public class FakeType {\n "); //$NON-NLS-1$
-// if(isStatic) {
-// prefix.append("static "); //$NON-NLS-1$
-// }
-// prefix.append("{\n"); //$NON-NLS-1$
-// for (int i = 0; i < localVariableTypeNames.length; i++) {
-// prefix.append(AstNode.modifiersString(localVariableModifiers[i]));
-// prefix.append(' ');
-// prefix.append(localVariableTypeNames[i]);
-// prefix.append(' ');
-// prefix.append(localVariableNames[i]);
-// prefix.append(';');
-// }
-//
-// char[] fakeSource = CharOperation.concat(prefix.toString().toCharArray(), snippet, "}}".toCharArray());//$NON-NLS-1$
-// offset = prefix.length();
-//
-// String encoding = JavaCore.getOption(JavaCore.CORE_ENCODING);
-// BasicCompilationUnit fakeUnit = new BasicCompilationUnit(
-// fakeSource,
-// null,
-// "FakeType.java", //$NON-NLS-1$
-// encoding);
-//
-// actualCompletionPosition = prefix.length() + position - 1;
-//
-// CompilationResult fakeResult = new CompilationResult(fakeUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
-// CompilationUnitDeclaration fakeAST = parser.dietParse(fakeUnit, fakeResult, actualCompletionPosition);
-//
-// parseMethod(fakeAST, actualCompletionPosition);
-//
-// return (Initializer)fakeAST.types[0].fields[0];
-// }
-
- /**
- * Ask the engine to compute a completion at the specified position
- * of the given compilation unit.
- *
- * @return void
- * completion results are answered through a requestor.
- *
- * @param sourceUnit net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit
- * the source of the current compilation unit.
- *
- * @param completionPosition int
- * a position in the source where the completion is taking place.
- * This position is relative to the source provided.
- */
- public void complete(ICompilationUnit sourceUnit, int completionPosition, int offset) {
-
- if(DEBUG) {
- System.out.print("COMPLETION IN "); //$NON-NLS-1$
- System.out.print(sourceUnit.getFileName());
- System.out.print(" AT POSITION "); //$NON-NLS-1$
- System.out.println(completionPosition);
- System.out.println("COMPLETION - Source :"); //$NON-NLS-1$
- System.out.println(sourceUnit.getContents());
- }
- try {
- actualCompletionPosition = completionPosition - 1;
- this.offset = offset;
- // for now until we can change the UI.
- CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
- CompilationUnitDeclaration parsedUnit = parser.dietParse(sourceUnit, result, actualCompletionPosition);
-
- // boolean completionNodeFound = false;
- if (parsedUnit != null) {
- if(DEBUG) {
- System.out.println("COMPLETION - Diet AST :"); //$NON-NLS-1$
- System.out.println(parsedUnit.toString());
- }
-
- // scan the package & import statements first
- if (parsedUnit.currentPackage instanceof CompletionOnPackageReference) {
- findPackages((CompletionOnPackageReference) parsedUnit.currentPackage);
- return;
- }
-
- ImportReference[] imports = parsedUnit.imports;
- if (imports != null) {
- for (int i = 0, length = imports.length; i < length; i++) {
- ImportReference importReference = imports[i];
- if (importReference instanceof CompletionOnImportReference) {
- findImports((CompletionOnImportReference) importReference);
- return;
- }
- }
- }
-
- if (parsedUnit.types != null) {
- try {
- lookupEnvironment.buildTypeBindings(parsedUnit);
-
- if ((unitScope = parsedUnit.scope) != null) {
- source = sourceUnit.getContents();
- lookupEnvironment.completeTypeBindings(parsedUnit, true);
- parsedUnit.scope.faultInTypes();
- parseMethod(parsedUnit, actualCompletionPosition);
- if(DEBUG) {
- System.out.println("COMPLETION - AST :"); //$NON-NLS-1$
- System.out.println(parsedUnit.toString());
- }
- parsedUnit.resolve();
- }
- } catch (CompletionNodeFound e) {
- // completionNodeFound = true;
- if (e.astNode != null) {
- if(DEBUG) {
- System.out.print("COMPLETION - Completion node : "); //$NON-NLS-1$
- System.out.println(e.astNode.toString());
- }
- // if null then we found a problem in the completion node
- complete(e.astNode, e.qualifiedBinding, e.scope);
- }
- }
- }
- }
-
- /* Ignore package, import, class & interface keywords for now...
- if (!completionNodeFound) {
- if (parsedUnit == null || parsedUnit.types == null) {
- // this is not good enough... can still be trying to define a second type
- CompletionScanner scanner = (CompletionScanner) parser.scanner;
- setSourceRange(scanner.completedIdentifierStart, scanner.completedIdentifierEnd);
- findKeywords(scanner.completionIdentifier, mainDeclarations, null);
- }
- // currently have no way to know if extends/implements are possible keywords
- }
- */
- } catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D
- } catch (InvalidCursorLocation e) { // may eventually report a usefull error
- } catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object
- } catch (CompletionNodeFound e){ // internal failure - bugs 5618
- } finally {
- reset();
- }
- }
-
- private TypeBinding[] computeTypes(Expression[] arguments, BlockScope scope) {
-
- if (arguments == null)
- return null;
-
- int argsLength = arguments.length;
- TypeBinding[] argTypes = new TypeBinding[argsLength];
- for (int a = argsLength; --a >= 0;)
- argTypes[a] = arguments[a].resolveType(scope);
- return argTypes;
- }
-
- private void findAnonymousType(
- ReferenceBinding currentType,
- TypeBinding[] argTypes,
- Scope scope,
- InvocationSite invocationSite) {
-
- if (currentType.isInterface()) {
- char[] completion = TypeConstants.NoChar;
- // nothing to insert - do not want to replace the existing selector & arguments
- if (source == null
- || source.length <= endPosition
- || source[endPosition] != ')')
- completion = new char[] { ')' };
-
- requestor.acceptAnonymousType(
- currentType.qualifiedPackageName(),
- currentType.qualifiedSourceName(),
- TypeConstants.NoCharChar,
- TypeConstants.NoCharChar,
- TypeConstants.NoCharChar,
- completion,
- IConstants.AccPublic,
- endPosition - offset,
- endPosition - offset,
- R_DEFAULT);
- } else {
- findConstructors(
- currentType,
- argTypes,
- scope,
- invocationSite,
- true);
- }
- }
-
- private void findClassField(char[] token, TypeBinding receiverType, Scope scope) {
-
- if (token == null)
- return;
-
- if (token.length <= classField.length
- && CharOperation.prefixEquals(token, classField, false /* ignore case */
- )) {
- int relevance = R_DEFAULT;
- relevance += computeRelevanceForCaseMatching(token, classField);
- relevance += computeRelevanceForExpectingType(scope.getJavaLangClass());
-
- requestor.acceptField(
- NoChar,
- NoChar,
- classField,
- NoChar,
- NoChar,
- classField,
- CompilerModifiers.AccStatic | CompilerModifiers.AccPublic,
- startPosition - offset,
- endPosition - offset,
- relevance);
- }
- }
-
- private void findConstructors(
- ReferenceBinding currentType,
- TypeBinding[] argTypes,
- Scope scope,
- InvocationSite invocationSite,
- boolean forAnonymousType) {
-
- // No visibility checks can be performed without the scope & invocationSite
- MethodBinding[] methods = currentType.availableMethods();
- if(methods != null) {
- int minArgLength = argTypes == null ? 0 : argTypes.length;
- next : for (int f = methods.length; --f >= 0;) {
- MethodBinding constructor = methods[f];
- if (constructor.isConstructor()) {
-
- if (constructor.isSynthetic()) continue next;
-
- if (options.checkVisibility
- && !constructor.canBeSeenBy(invocationSite, scope)) continue next;
-
- TypeBinding[] parameters = constructor.parameters;
- int paramLength = parameters.length;
- if (minArgLength > paramLength)
- continue next;
- for (int a = minArgLength; --a >= 0;)
- if (argTypes[a] != null) // can be null if it could not be resolved properly
- if (!Scope.areTypesCompatible(argTypes[a], constructor.parameters[a]))
- continue next;
-
- char[][] parameterPackageNames = new char[paramLength][];
- char[][] parameterTypeNames = new char[paramLength][];
- for (int i = 0; i < paramLength; i++) {
- TypeBinding type = parameters[i];
- parameterPackageNames[i] = type.qualifiedPackageName();
- parameterTypeNames[i] = type.qualifiedSourceName();
- }
- char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);
-
- char[] completion = TypeConstants.NoChar;
- // nothing to insert - do not want to replace the existing selector & arguments
- if (source == null
- || source.length <= endPosition
- || source[endPosition] != ')')
- completion = new char[] { ')' };
-
- if(forAnonymousType){
- requestor.acceptAnonymousType(
- currentType.qualifiedPackageName(),
- currentType.qualifiedSourceName(),
- parameterPackageNames,
- parameterTypeNames,
- parameterNames,
- completion,
- constructor.modifiers,
- endPosition - offset,
- endPosition - offset,
- R_DEFAULT);
- } else {
- requestor.acceptMethod(
- currentType.qualifiedPackageName(),
- currentType.qualifiedSourceName(),
- currentType.sourceName(),
- parameterPackageNames,
- parameterTypeNames,
- parameterNames,
- TypeConstants.NoChar,
- TypeConstants.NoChar,
- completion,
- constructor.modifiers,
- endPosition - offset,
- endPosition - offset,
- R_DEFAULT);
- }
- }
- }
- }
- }
-
- // Helper method for findFields(char[], ReferenceBinding, Scope, ObjectVector, boolean)
- private void findFields(
- char[] fieldName,
- FieldBinding[] fields,
- Scope scope,
- ObjectVector fieldsFound,
- ObjectVector localsFound,
- boolean onlyStaticFields,
- ReferenceBinding receiverType,
- InvocationSite invocationSite,
- Scope invocationScope,
- boolean implicitCall) {
-
- // Inherited fields which are hidden by subclasses are filtered out
- // No visibility checks can be performed without the scope & invocationSite
-
- int fieldLength = fieldName.length;
- next : for (int f = fields.length; --f >= 0;) {
- FieldBinding field = fields[f];
-
- if (field.isSynthetic()) continue next;
-
- if (onlyStaticFields && !field.isStatic()) continue next;
-
- if (fieldLength > field.name.length) continue next;
-
- if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)) continue next;
-
- if (options.checkVisibility
- && !field.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
-
- boolean prefixRequired = false;
-
- for (int i = fieldsFound.size; --i >= 0;) {
- Object[] other = (Object[])fieldsFound.elementAt(i);
- FieldBinding otherField = (FieldBinding) other[0];
- ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
- if (field == otherField && receiverType == otherReceiverType)
- continue next;
- if (CharOperation.equals(field.name, otherField.name, true)) {
- if (field.declaringClass.isSuperclassOf(otherField.declaringClass))
- continue next;
- if (otherField.declaringClass.isInterface())
- if (field.declaringClass.implementsInterface(otherField.declaringClass, true))
- continue next;
- if (field.declaringClass.isInterface())
- if (otherField.declaringClass.implementsInterface(field.declaringClass, true))
- continue next;
- prefixRequired = true;
- }
- }
-
- for (int l = localsFound.size; --l >= 0;) {
- LocalVariableBinding local = (LocalVariableBinding) localsFound.elementAt(l);
-
- if (CharOperation.equals(field.name, local.name, true)) {
- SourceTypeBinding declarationType = scope.enclosingSourceType();
- if (declarationType.isAnonymousType() && declarationType != invocationScope.enclosingSourceType()) {
- continue next;
- }
- prefixRequired = true;
- break;
- }
- }
-
- fieldsFound.add(new Object[]{field, receiverType});
-
- char[] completion = field.name;
-
- if(prefixRequired || options.forceImplicitQualification){
- char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), field.isStatic());
- completion = CharOperation.concat(prefix,completion,'.');
- }
-
- int relevance = R_DEFAULT;
- relevance += computeRelevanceForCaseMatching(fieldName, field.name);
- relevance += computeRelevanceForExpectingType(field.type);
-
- requestor
- .acceptField(
- field.declaringClass.qualifiedPackageName(),
- field.declaringClass.qualifiedSourceName(),
- field.name,
- field.type.qualifiedPackageName(),
- field.type.qualifiedSourceName(),
- completion,
- // may include some qualification to resolve ambiguities
- field.modifiers, startPosition - offset, endPosition - offset,
- relevance);
- }
- }
-
- private void findFields(
- char[] fieldName,
- ReferenceBinding receiverType,
- Scope scope,
- ObjectVector fieldsFound,
- ObjectVector localsFound,
- boolean onlyStaticFields,
- InvocationSite invocationSite,
- Scope invocationScope,
- boolean implicitCall) {
-
- if (fieldName == null)
- return;
-
- ReferenceBinding currentType = receiverType;
- ReferenceBinding[][] interfacesToVisit = null;
- int lastPosition = -1;
- do {
-
- ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
- if (itsInterfaces != NoSuperInterfaces) {
-
- if (interfacesToVisit == null)
- interfacesToVisit = new ReferenceBinding[5][];
-
- if (++lastPosition == interfacesToVisit.length)
- System.arraycopy(
- interfacesToVisit,
- 0,
- interfacesToVisit = new ReferenceBinding[lastPosition * 2][],
- 0,
- lastPosition);
- interfacesToVisit[lastPosition] = itsInterfaces;
- }
-
- FieldBinding[] fields = currentType.availableFields();
- if(fields != null) {
- findFields(
- fieldName,
- fields,
- scope,
- fieldsFound,
- localsFound,
- onlyStaticFields,
- receiverType,
- invocationSite,
- invocationScope,
- implicitCall);
- }
- currentType = currentType.superclass();
- } while (currentType != null);
-
- if (interfacesToVisit != null) {
- for (int i = 0; i <= lastPosition; i++) {
- ReferenceBinding[] interfaces = interfacesToVisit[i];
- for (int j = 0, length = interfaces.length; j < length; j++) {
-
- ReferenceBinding anInterface = interfaces[j];
- if ((anInterface.tagBits & TagBits.InterfaceVisited) == 0) {
- // if interface as not already been visited
- anInterface.tagBits |= TagBits.InterfaceVisited;
-
- FieldBinding[] fields = anInterface.availableFields();
- if(fields != null) {
- findFields(
- fieldName,
- fields,
- scope,
- fieldsFound,
- localsFound,
- onlyStaticFields,
- receiverType,
- invocationSite,
- invocationScope,
- implicitCall);
- }
-
- ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
- if (itsInterfaces != NoSuperInterfaces) {
- if (++lastPosition == interfacesToVisit.length)
- System.arraycopy(
- interfacesToVisit,
- 0,
- interfacesToVisit = new ReferenceBinding[lastPosition * 2][],
- 0,
- lastPosition);
- interfacesToVisit[lastPosition] = itsInterfaces;
- }
- }
- }
- }
-
- // bit reinitialization
- for (int i = 0; i <= lastPosition; i++) {
- ReferenceBinding[] interfaces = interfacesToVisit[i];
- for (int j = 0, length = interfaces.length; j < length; j++)
- interfaces[j].tagBits &= ~TagBits.InterfaceVisited;
- }
- }
- }
-
- private void findFieldsAndMethods(
- char[] token,
- TypeBinding receiverType,
- Scope scope,
- InvocationSite invocationSite,
- Scope invocationScope,
- boolean implicitCall) {
-
- if (token == null)
- return;
-
- if (receiverType.isBaseType())
- return; // nothing else is possible with base types
-
- if (receiverType.isArrayType()) {
- if (token.length <= lengthField.length
- && CharOperation.prefixEquals(token, lengthField, false /* ignore case */
- )) {
-
- int relevance = R_DEFAULT;
- relevance += computeRelevanceForCaseMatching(token,lengthField);
- relevance += computeRelevanceForExpectingType(BaseTypes.IntBinding);
-
- requestor.acceptField(
- NoChar,
- NoChar,
- lengthField,
- NoChar,
- NoChar,
- lengthField,
- CompilerModifiers.AccPublic,
- startPosition - offset,
- endPosition - offset,
- relevance);
- }
- receiverType = scope.getJavaLangObject();
- }
-
- findFields(
- token,
- (ReferenceBinding) receiverType,
- scope,
- new ObjectVector(),
- new ObjectVector(),
- false,
- invocationSite,
- invocationScope,
- implicitCall);
-
- findMethods(
- token,
- null,
- (ReferenceBinding) receiverType,
- scope,
- new ObjectVector(),
- false,
- false,
- false,
- invocationSite,
- invocationScope,
- implicitCall);
- }
-
- private void findImports(CompletionOnImportReference importReference) {
- char[][] tokens = importReference.tokens;
-
- char[] importName = CharOperation.concatWith(tokens, '.');
-
- if (importName.length == 0)
- return;
-
- char[] lastToken = tokens[tokens.length - 1];
- if(lastToken != null && lastToken.length == 0)
- importName = CharOperation.concat(importName, new char[]{'.'});
-
- resolvingImports = true;
- setSourceRange(
- importReference.sourceStart,
- importReference.declarationSourceEnd);
-
- token = importName;
- // want to replace the existing .*;
- nameEnvironment.findPackages(importName, this);
- nameEnvironment.findTypes(importName, this);
- }
-
- // what about onDemand types? Ignore them since it does not happen!
- // import p1.p2.A.*;
- private void findKeywords(char[] keyword, char[][] choices, Scope scope) {
-
- int length = keyword.length;
- if (length > 0)
- for (int i = 0; i < choices.length; i++)
- if (length <= choices[i].length
- && CharOperation.prefixEquals(keyword, choices[i], false /* ignore case */
- )){
- int relevance = R_DEFAULT;
- relevance += computeRelevanceForCaseMatching(keyword, choices[i]);
-
- requestor.acceptKeyword(choices[i], startPosition - offset, endPosition - offset,relevance);
- }
- }
-
- // Helper method for findMemberTypes(char[], ReferenceBinding, Scope)
- private void findMemberTypes(
- char[] typeName,
- ReferenceBinding[] memberTypes,
- ObjectVector typesFound,
- ReferenceBinding receiverType,
- SourceTypeBinding invocationType) {
-
- // Inherited member types which are hidden by subclasses are filtered out
- // No visibility checks can be performed without the scope & invocationSite
- int typeLength = typeName.length;
- next : for (int m = memberTypes.length; --m >= 0;) {
- ReferenceBinding memberType = memberTypes[m];
- // if (!wantClasses && memberType.isClass()) continue next;
- // if (!wantInterfaces && memberType.isInterface()) continue next;
- if (typeLength > memberType.sourceName.length)
- continue next;
-
- if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false
- /* ignore case */
- ))
- continue next;
-
- if (options.checkVisibility
- && !memberType.canBeSeenBy(receiverType, invocationType))
- continue next;
-
- for (int i = typesFound.size; --i >= 0;) {
- ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(i);
-
- if (memberType == otherType)
- continue next;
-
- if (CharOperation.equals(memberType.sourceName, otherType.sourceName, true)) {
-
- if (memberType.enclosingType().isSuperclassOf(otherType.enclosingType()))
- continue next;
-
- if (otherType.enclosingType().isInterface())
- if (memberType.enclosingType()
- .implementsInterface(otherType.enclosingType(), true))
- continue next;
-
- if (memberType.enclosingType().isInterface())
- if (otherType.enclosingType()
- .implementsInterface(memberType.enclosingType(), true))
- continue next;
- }
- }
-
- typesFound.add(memberType);
-
- int relevance = R_DEFAULT;
- relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
- relevance += computeRelevanceForExpectingType(memberType);
-
- if (memberType.isClass()) {
- relevance += computeRelevanceForClass();
- requestor.acceptClass(
- memberType.qualifiedPackageName(),
- memberType.qualifiedSourceName(),
- memberType.sourceName(),
- memberType.modifiers,
- startPosition - offset,
- endPosition - offset,
- relevance);
-
- } else {
- relevance += computeRelevanceForInterface();
- requestor.acceptInterface(
- memberType.qualifiedPackageName(),
- memberType.qualifiedSourceName(),
- memberType.sourceName(),
- memberType.modifiers,
- startPosition - offset,
- endPosition - offset,
- relevance);
- }
- }
- }
-
- private void findMemberTypes(
- char[] typeName,
- ReferenceBinding receiverType,
- Scope scope,
- SourceTypeBinding typeInvocation) {
-
- ReferenceBinding currentType = receiverType;
- if (typeName == null)
- return;
-
- if (currentType.superInterfaces() == null)
- return; // we're trying to find a supertype
-
- ObjectVector typesFound = new ObjectVector();
- if (insideQualifiedReference
- || typeName.length == 0) { // do not search up the hierarchy
-
- findMemberTypes(
- typeName,
- currentType.memberTypes(),
- typesFound,
- receiverType,
- typeInvocation);
- return;
- }
-
- ReferenceBinding[][] interfacesToVisit = null;
- int lastPosition = -1;
-
- do {
-
- ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
- if (itsInterfaces != NoSuperInterfaces) {
-
- if (interfacesToVisit == null)
- interfacesToVisit = new ReferenceBinding[5][];
-
- if (++lastPosition == interfacesToVisit.length)
- System.arraycopy(
- interfacesToVisit,
- 0,
- interfacesToVisit = new ReferenceBinding[lastPosition * 2][],
- 0,
- lastPosition);
- interfacesToVisit[lastPosition] = itsInterfaces;
- }
-
- findMemberTypes(
- typeName,
- currentType.memberTypes(),
- typesFound,
- receiverType,
- typeInvocation);
- currentType = currentType.superclass();
-
- } while (currentType != null);
-
- if (interfacesToVisit != null) {
- for (int i = 0; i <= lastPosition; i++) {
- ReferenceBinding[] interfaces = interfacesToVisit[i];
- for (int j = 0, length = interfaces.length; j < length; j++) {
-
- ReferenceBinding anInterface = interfaces[j];
- if ((anInterface.tagBits & TagBits.InterfaceVisited) == 0) {
- // if interface as not already been visited
- anInterface.tagBits |= TagBits.InterfaceVisited;
-
- findMemberTypes(
- typeName,
- anInterface.memberTypes(),
- typesFound,
- receiverType,
- typeInvocation);
-
- ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
- if (itsInterfaces != NoSuperInterfaces) {
-
- if (++lastPosition == interfacesToVisit.length)
- System.arraycopy(
- interfacesToVisit,
- 0,
- interfacesToVisit = new ReferenceBinding[lastPosition * 2][],
- 0,
- lastPosition);
- interfacesToVisit[lastPosition] = itsInterfaces;
- }
- }
- }
- }
-
- // bit reinitialization
- for (int i = 0; i <= lastPosition; i++) {
- ReferenceBinding[] interfaces = interfacesToVisit[i];
- for (int j = 0, length = interfaces.length; j < length; j++)
- interfaces[j].tagBits &= ~TagBits.InterfaceVisited;
- }
- }
- }
-
- private void findIntefacesMethods(
- char[] selector,
- TypeBinding[] argTypes,
- ReferenceBinding receiverType,
- ReferenceBinding[] itsInterfaces,
- Scope scope,
- ObjectVector methodsFound,
- boolean onlyStaticMethods,
- boolean exactMatch,
- boolean isCompletingDeclaration,
- InvocationSite invocationSite,
- Scope invocationScope,
- boolean implicitCall) {
-
- if (selector == null)
- return;
-
- if (itsInterfaces != NoSuperInterfaces) {
- ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][];
- int lastPosition = 0;
- interfacesToVisit[lastPosition] = itsInterfaces;
-
- for (int i = 0; i <= lastPosition; i++) {
- ReferenceBinding[] interfaces = interfacesToVisit[i];
-
- for (int j = 0, length = interfaces.length; j < length; j++) {
- ReferenceBinding currentType = interfaces[j];
-
- if ((currentType.tagBits & TagBits.InterfaceVisited) == 0) {
- // if interface as not already been visited
- currentType.tagBits |= TagBits.InterfaceVisited;
-
- MethodBinding[] methods = currentType.availableMethods();
- if(methods != null) {
- if(isCompletingDeclaration){
-
- findLocalMethodDeclarations(
- selector,
- methods,
- scope,
- methodsFound,
- onlyStaticMethods,
- exactMatch,
- receiverType);
-
- } else {
-
- findLocalMethods(
- selector,
- argTypes,
- methods,
- scope,
- methodsFound,
- onlyStaticMethods,
- exactMatch,
- receiverType,
- invocationSite,
- invocationScope,
- implicitCall);
- }
- }
-
- itsInterfaces = currentType.superInterfaces();
- if (itsInterfaces != NoSuperInterfaces) {
-
- if (++lastPosition == interfacesToVisit.length)
- System.arraycopy(
- interfacesToVisit,
- 0,
- interfacesToVisit = new ReferenceBinding[lastPosition * 2][],
- 0,
- lastPosition);
- interfacesToVisit[lastPosition] = itsInterfaces;
- }
- }
- }
- }
-
- // bit reinitialization
- for (int i = 0; i <= lastPosition; i++) {
- ReferenceBinding[] interfaces = interfacesToVisit[i];
-
- for (int j = 0, length = interfaces.length; j < length; j++){
- interfaces[j].tagBits &= ~TagBits.InterfaceVisited;
- }
- }
- }
- }
-
- private void findImplicitMessageSends(
- char[] token,
- TypeBinding[] argTypes,
- Scope scope,
- InvocationSite invocationSite,
- Scope invocationScope) {
-
- if (token == null)
- return;
-
- boolean staticsOnly = false;
- // need to know if we're in a static context (or inside a constructor)
- ObjectVector methodsFound = new ObjectVector();
-
- done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
-
- switch (scope.kind) {
-
- case Scope.METHOD_SCOPE :
- // handle the error case inside an explicit constructor call (see MethodScope>>findField)
- MethodScope methodScope = (MethodScope) scope;
- staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
- break;
-
- case Scope.CLASS_SCOPE :
- ClassScope classScope = (ClassScope) scope;
- SourceTypeBinding enclosingType = classScope.referenceContext.binding;
- findMethods(
- token,
- argTypes,
- enclosingType,
- classScope,
- methodsFound,
- staticsOnly,
- true,
- false,
- invocationSite,
- invocationScope,
- true);
- staticsOnly |= enclosingType.isStatic();
- break;
-
- case Scope.COMPILATION_UNIT_SCOPE :
- break done;
- }
- scope = scope.parent;
- }
- }
-
- // Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
- private void findLocalMethods(
- char[] methodName,
- TypeBinding[] argTypes,
- MethodBinding[] methods,
- Scope scope,
- ObjectVector methodsFound,
- boolean onlyStaticMethods,
- boolean exactMatch,
- ReferenceBinding receiverType,
- InvocationSite invocationSite,
- Scope invocationScope,
- boolean implicitCall) {
-
- // Inherited methods which are hidden by subclasses are filtered out
- // No visibility checks can be performed without the scope & invocationSite
-
- int methodLength = methodName.length;
- int minArgLength = argTypes == null ? 0 : argTypes.length;
-
- next : for (int f = methods.length; --f >= 0;) {
- MethodBinding method = methods[f];
-
- if (method.isSynthetic()) continue next;
-
- if (method.isDefaultAbstract()) continue next;
-
- if (method.isConstructor()) continue next;
-
- // if (noVoidReturnType && method.returnType == BaseTypes.VoidBinding) continue next;
- if (onlyStaticMethods && !method.isStatic()) continue next;
-
- if (options.checkVisibility
- && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
-
- if (exactMatch) {
- if (!CharOperation.equals(methodName, method.selector, false /* ignore case */
- ))
- continue next;
-
- } else {
-
- if (methodLength > method.selector.length)
- continue next;
-
- if (!CharOperation.prefixEquals(methodName, method.selector, false
- /* ignore case */
- ))
- continue next;
- }
- if (minArgLength > method.parameters.length)
- continue next;
-
- for (int a = minArgLength; --a >= 0;){
- if (argTypes[a] != null){ // can be null if it could not be resolved properly
- if (!Scope.areTypesCompatible(argTypes[a], method.parameters[a])) {
- continue next;
- }
- }
- }
-
- boolean prefixRequired = false;
-
- for (int i = methodsFound.size; --i >= 0;) {
- Object[] other = (Object[]) methodsFound.elementAt(i);
- MethodBinding otherMethod = (MethodBinding) other[0];
- ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
- if (method == otherMethod && receiverType == otherReceiverType)
- continue next;
-
- if (CharOperation.equals(method.selector, otherMethod.selector, true)
- && method.areParametersEqual(otherMethod)) {
-
- if (method.declaringClass.isSuperclassOf(otherMethod.declaringClass))
- continue next;
-
- if (otherMethod.declaringClass.isInterface())
- if (method
- .declaringClass
- .implementsInterface(otherMethod.declaringClass, true))
- continue next;
-
- if (method.declaringClass.isInterface())
- if(otherMethod
- .declaringClass
- .implementsInterface(method.declaringClass,true))
- continue next;
- prefixRequired = true;
- }
- }
-
- methodsFound.add(new Object[]{method, receiverType});
- int length = method.parameters.length;
- char[][] parameterPackageNames = new char[length][];
- char[][] parameterTypeNames = new char[length][];
-
- for (int i = 0; i < length; i++) {
- TypeBinding type = method.parameters[i];
- parameterPackageNames[i] = type.qualifiedPackageName();
- parameterTypeNames[i] = type.qualifiedSourceName();
- }
- char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
-
- char[] completion = TypeConstants.NoChar;
-
- int previousStartPosition = startPosition;
-
- // nothing to insert - do not want to replace the existing selector & arguments
- if (!exactMatch) {
- if (source != null
- && source.length > endPosition
- && source[endPosition] == '(')
- completion = method.selector;
- else
- completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
- } else {
- if(prefixRequired && (source != null)) {
- completion = CharOperation.subarray(source, startPosition, endPosition);
- } else {
- startPosition = endPosition;
- }
- }
-
- if(prefixRequired || options.forceImplicitQualification){
- char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), method.isStatic());
- completion = CharOperation.concat(prefix,completion,'.');
- }
-
- int relevance = R_DEFAULT;
- relevance += computeRelevanceForCaseMatching(methodName, method.selector);
- relevance += computeRelevanceForExpectingType(method.returnType);
-
- requestor.acceptMethod(
- method.declaringClass.qualifiedPackageName(),
- method.declaringClass.qualifiedSourceName(),
- method.selector,
- parameterPackageNames,
- parameterTypeNames,
- parameterNames,
- method.returnType.qualifiedPackageName(),
- method.returnType.qualifiedSourceName(),
- completion,
- method.modifiers,
- startPosition - offset,
- endPosition - offset,
- relevance);
- startPosition = previousStartPosition;
- }
- }
-
- private int computeRelevanceForCaseMatching(char[] token, char[] proposalName){
- if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
- return R_CASE;
- } else {
- return R_DEFAULT;
- }
- }
- private int computeRelevanceForClass(){
- if(assistNodeIsClass) {
- return R_CLASS;
- }
- return 0;
- }
- private int computeRelevanceForInterface(){
- if(assistNodeIsInterface) {
- return R_INTERFACE;
- }
- return R_DEFAULT;
- }
- private int computeRelevanceForException(char[] proposalName){
-
- if(assistNodeIsException &&
- (CharOperation.match(EXCEPTION_PATTERN, proposalName, false) ||
- CharOperation.match(ERROR_PATTERN, proposalName, false))) {
- return R_EXCEPTION;
- }
- return R_DEFAULT;
- }
- private int computeRelevanceForExpectingType(TypeBinding proposalType){
- if(expectedTypes != null && proposalType != null) {
- for (int i = 0; i < expectedTypes.length; i++) {
- if(Scope.areTypesCompatible(proposalType, expectedTypes[i])) {
- return R_EXPECTED_TYPE;
- }
- }
- }
- return R_DEFAULT;
- }
- private int computeRelevanceForExpectingType(char[] packageName, char[] typeName){
- if(expectedTypes != null) {
- for (int i = 0; i < expectedTypes.length; i++) {
- if(CharOperation.equals(expectedTypes[i].qualifiedPackageName(), packageName) &&
- CharOperation.equals(expectedTypes[i].qualifiedSourceName(), typeName)) {
- return R_EXPECTED_TYPE;
- }
- }
- }
- return R_DEFAULT;
- }
-
- // Helper method for findMethods(char[], MethodBinding[], Scope, ObjectVector, boolean, boolean, boolean, TypeBinding)
- private void findLocalMethodDeclarations(
- char[] methodName,
- MethodBinding[] methods,
- Scope scope,
- ObjectVector methodsFound,
- // boolean noVoidReturnType, how do you know?
- boolean onlyStaticMethods,
- boolean exactMatch,
- ReferenceBinding receiverType) {
-
- // Inherited methods which are hidden by subclasses are filtered out
- // No visibility checks can be performed without the scope & invocationSite
- int methodLength = methodName.length;
- next : for (int f = methods.length; --f >= 0;) {
-
- MethodBinding method = methods[f];
- if (method.isSynthetic()) continue next;
-
- if (method.isDefaultAbstract()) continue next;
-
- if (method.isConstructor()) continue next;
-
- if (method.isFinal()) continue next;
-
- // if (noVoidReturnType && method.returnType == BaseTypes.VoidBinding) continue next;
- if (onlyStaticMethods && !method.isStatic()) continue next;
-
- if (options.checkVisibility
- && !method.canBeSeenBy(receiverType, FakeInvocationSite , scope)) continue next;
-
- if (exactMatch) {
- if (!CharOperation.equals(methodName, method.selector, false /* ignore case */
- ))
- continue next;
-
- } else {
-
- if (methodLength > method.selector.length)
- continue next;
-
- if (!CharOperation.prefixEquals(methodName, method.selector, false
- /* ignore case */
- ))
- continue next;
- }
-
- for (int i = methodsFound.size; --i >= 0;) {
- MethodBinding otherMethod = (MethodBinding) methodsFound.elementAt(i);
- if (method == otherMethod)
- continue next;
-
- if (CharOperation.equals(method.selector, otherMethod.selector, true)
- && method.areParametersEqual(otherMethod)) {
- continue next;
- }
- }
-
- methodsFound.add(method);
-
- int length = method.parameters.length;
- char[][] parameterPackageNames = new char[length][];
- char[][] parameterTypeNames = new char[length][];
-
- for (int i = 0; i < length; i++) {
- TypeBinding type = method.parameters[i];
- parameterPackageNames[i] = type.qualifiedPackageName();
- parameterTypeNames[i] = type.qualifiedSourceName();
- }
-
- char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
-
- StringBuffer completion = new StringBuffer(10);
- // flush uninteresting modifiers
- int insertedModifiers = method.modifiers & ~(CompilerModifiers.AccNative | CompilerModifiers.AccAbstract);
-
- if (!exactMatch) {
- if(insertedModifiers != CompilerModifiers.AccDefault){
- completion.append(AstNode.modifiersString(insertedModifiers));
- }
- char[] returnPackageName = method.returnType.qualifiedPackageName();
- char[] returnTypeName = method.returnType.qualifiedSourceName();
- if(mustQualifyType(returnPackageName, returnTypeName)) {
- completion.append(CharOperation.concat(returnPackageName, returnTypeName,'.'));
- } else {
- completion.append(method.returnType.sourceName());
- }
- completion.append(' ');
- completion.append(method.selector);
- completion.append('(');
-
- for(int i = 0; i < length ; i++){
- if(mustQualifyType(parameterPackageNames[i], parameterTypeNames[i])){
- completion.append(CharOperation.concat(parameterPackageNames[i], parameterTypeNames[i], '.'));
- } else {
- completion.append(parameterTypeNames[i]);
- }
- completion.append(' ');
- if(parameterNames != null){
- completion.append(parameterNames[i]);
- } else {
- completion.append('%');
- }
- if(i != (length - 1))
- completion.append(',');
- }
- completion.append(')');
-
- ReferenceBinding[] exceptions = method.thrownExceptions;
-
- if (exceptions != null && exceptions.length > 0){
- completion.append(' ');
- completion.append(THROWS);
- completion.append(' ');
- for(int i = 0; i < exceptions.length ; i++){
- ReferenceBinding exception = exceptions[i];
-
- char[] exceptionPackageName = exception.qualifiedPackageName();
- char[] exceptionTypeName = exception.qualifiedSourceName();
-
- if(i != 0){
- completion.append(',');
- completion.append(' ');
- }
-
- if(mustQualifyType(exceptionPackageName, exceptionTypeName)){
- completion.append(CharOperation.concat(exceptionPackageName, exceptionTypeName, '.'));
- } else {
- completion.append(exception.sourceName());
- }
- }
- }
- }
-
- int relevance = R_DEFAULT;
- relevance += computeRelevanceForCaseMatching(methodName, method.selector);
-
- requestor.acceptMethodDeclaration(
- method.declaringClass.qualifiedPackageName(),
- method.declaringClass.qualifiedSourceName(),
- method.selector,
- parameterPackageNames,
- parameterTypeNames,
- parameterNames,
- method.returnType.qualifiedPackageName(),
- method.returnType.qualifiedSourceName(),
- completion.toString().toCharArray(),
- method.modifiers,
- startPosition - offset,
- endPosition - offset,
- relevance);
- }
- }
- private void findMethods(
- char[] selector,
- TypeBinding[] argTypes,
- ReferenceBinding receiverType,
- Scope scope,
- ObjectVector methodsFound,
- boolean onlyStaticMethods,
- boolean exactMatch,
- boolean isCompletingDeclaration,
- InvocationSite invocationSite,
- Scope invocationScope,
- boolean implicitCall) {
- if (selector == null)
- return;
-
- if(isCompletingDeclaration) {
- MethodBinding[] methods = receiverType.availableMethods();
- if (methods != null){
- for (int i = 0; i < methods.length; i++) {
- if(!methods[i].isDefaultAbstract()) {
- methodsFound.add(methods[i]);
- }
- }
- }
- }
-
- ReferenceBinding currentType = receiverType;
- if (receiverType.isInterface()) {
- if(isCompletingDeclaration) {
- findIntefacesMethods(
- selector,
- argTypes,
- receiverType,
- currentType.superInterfaces(),
- scope,
- methodsFound,
- onlyStaticMethods,
- exactMatch,
- isCompletingDeclaration,
- invocationSite,
- invocationScope,
- implicitCall);
- } else {
- findIntefacesMethods(
- selector,
- argTypes,
- receiverType,
- new ReferenceBinding[]{currentType},
- scope,
- methodsFound,
- onlyStaticMethods,
- exactMatch,
- isCompletingDeclaration,
- invocationSite,
- invocationScope,
- implicitCall);
- }
-
- currentType = scope.getJavaLangObject();
- } else {
- if(isCompletingDeclaration){
- findIntefacesMethods(
- selector,
- argTypes,
- receiverType,
- currentType.superInterfaces(),
- scope,
- methodsFound,
- onlyStaticMethods,
- exactMatch,
- isCompletingDeclaration,
- invocationSite,
- invocationScope,
- implicitCall);
-
- currentType = receiverType.superclass();
- }
- }
- boolean hasPotentialDefaultAbstractMethods = true;
- while (currentType != null) {
-
- MethodBinding[] methods = currentType.availableMethods();
- if(methods != null) {
- if(isCompletingDeclaration){
- findLocalMethodDeclarations(
- selector,
- methods,
- scope,
- methodsFound,
- onlyStaticMethods,
- exactMatch,
- receiverType);
- } else{
- findLocalMethods(
- selector,
- argTypes,
- methods,
- scope,
- methodsFound,
- onlyStaticMethods,
- exactMatch,
- receiverType,
- invocationSite,
- invocationScope,
- implicitCall);
- }
- }
-
- if(hasPotentialDefaultAbstractMethods && currentType.isAbstract()){
- findIntefacesMethods(
- selector,
- argTypes,
- receiverType,
- currentType.superInterfaces(),
- scope,
- methodsFound,
- onlyStaticMethods,
- exactMatch,
- isCompletingDeclaration,
- invocationSite,
- invocationScope,
- implicitCall);
- } else {
- hasPotentialDefaultAbstractMethods = false;
- }
- currentType = currentType.superclass();
- }
- }
- private char[][] findMethodParameterNames(MethodBinding method, char[][] parameterTypeNames){
- ReferenceBinding bindingType = method.declaringClass;
-
- char[][] parameterNames = null;
-
- int length = parameterTypeNames.length;
-
- if (length == 0){
- return TypeConstants.NoCharChar;
- }
- // look into the corresponding unit if it is available
- if (bindingType instanceof SourceTypeBinding){
- SourceTypeBinding sourceType = (SourceTypeBinding) bindingType;
-
- if (sourceType.scope != null){
- TypeDeclaration parsedType;
-
- if ((parsedType = sourceType.scope.referenceContext) != null){
- AbstractMethodDeclaration methodDecl = parsedType.declarationOf(method);
-
- if (methodDecl != null){
- Argument[] arguments = methodDecl.arguments;
- parameterNames = new char[length][];
-
- for(int i = 0 ; i < length ; i++){
- parameterNames[i] = arguments[i].name;
- }
- }
- }
- }
- }
- // look into the model
- if(parameterNames == null){
- NameEnvironmentAnswer answer = nameEnvironment.findType(bindingType.compoundName);
-
- if(answer != null){
- if(answer.isSourceType()) {
- ISourceType sourceType = answer.getSourceTypes()[0];
- ISourceMethod[] sourceMethods = sourceType.getMethods();
- int len = sourceMethods == null ? 0 : sourceMethods.length;
- for(int i = 0; i < len ; i++){
- ISourceMethod sourceMethod = sourceMethods[i];
- char[][] argTypeNames = sourceMethod.getArgumentTypeNames();
-
- if(argTypeNames != null &&
- CharOperation.equals(method.selector,sourceMethod.getSelector()) &&
- CharOperation.equals(argTypeNames,parameterTypeNames)){
- parameterNames = sourceMethod.getArgumentNames();
- break;
- }
- }
- }
- }
- }
- return parameterNames;
- }
-
- private void findNestedTypes(
- char[] typeName,
- SourceTypeBinding currentType,
- Scope scope) {
- if (typeName == null)
- return;
-
- int typeLength = typeName.length;
-
- while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found
-
- switch (scope.kind) {
-
- case Scope.METHOD_SCOPE :
- case Scope.BLOCK_SCOPE :
- BlockScope blockScope = (BlockScope) scope;
-
- next : for (int i = 0, length = blockScope.scopeIndex; i < length; i++) {
-
- if (blockScope.subscopes[i] instanceof ClassScope) {
- SourceTypeBinding localType =
- ((ClassScope) blockScope.subscopes[i]).referenceContext.binding;
-
- if (!localType.isAnonymousType()) {
- if (typeLength > localType.sourceName.length)
- continue next;
- if (!CharOperation.prefixEquals(typeName, localType.sourceName, false
- /* ignore case */
- ))
- continue next;
-
- int relevance = R_DEFAULT;
- relevance += computeRelevanceForCaseMatching(typeName, localType.sourceName);
- relevance += computeRelevanceForExpectingType(localType);
- relevance += computeRelevanceForClass();
-
- requestor.acceptClass(
- localType.qualifiedPackageName(),
- localType.sourceName,
- localType.sourceName,
- localType.modifiers,
- startPosition - offset,
- endPosition - offset,
- relevance);
- }
- }
- }
- break;
-
- case Scope.CLASS_SCOPE :
- findMemberTypes(typeName, scope.enclosingSourceType(), scope, currentType);
- if (typeLength == 0)
- return; // do not search outside the class scope if no prefix was provided
- break;
-
- case Scope.COMPILATION_UNIT_SCOPE :
- return;
- }
- scope = scope.parent;
- }
- }
-
- private void findPackages(CompletionOnPackageReference packageStatement) {
-
- token = CharOperation.concatWith(packageStatement.tokens, '.');
- if (token.length == 0)
- return;
-
- setSourceRange(packageStatement.sourceStart, packageStatement.sourceEnd);
- nameEnvironment.findPackages(CharOperation.toLowerCase(token), this);
- }
-
- private void findTypesAndPackages(char[] token, Scope scope) {
-
- if (token == null)
- return;
-
- if (scope.enclosingSourceType() != null)
- findNestedTypes(token, scope.enclosingSourceType(), scope);
-
- if (unitScope != null) {
- int typeLength = token.length;
- SourceTypeBinding[] types = unitScope.topLevelTypes;
-
- for (int i = 0, length = types.length; i < length; i++) {
- SourceTypeBinding sourceType = types[i];
-
- if (typeLength > sourceType.sourceName.length) continue;
-
- if (!CharOperation.prefixEquals(token, sourceType.sourceName, false)) continue;
-
- int relevance = R_DEFAULT;
- relevance += computeRelevanceForCaseMatching(token, sourceType.sourceName);
- relevance += computeRelevanceForExpectingType(sourceType);
-
- if (sourceType.isClass()){
- relevance += computeRelevanceForClass();
- requestor.acceptClass(
- sourceType.qualifiedPackageName(),
- sourceType.sourceName(),
- sourceType.sourceName(),
- sourceType.modifiers,
- startPosition - offset,
- endPosition - offset,
- relevance);
- } else {
- relevance += computeRelevanceForInterface();
- requestor.acceptInterface(
- sourceType.qualifiedPackageName(),
- sourceType.sourceName(),
- sourceType.sourceName(),
- sourceType.modifiers,
- startPosition - offset,
- endPosition - offset,
- relevance);
- }
- }
- }
-
- if (token.length == 0)
- return;
-
- findKeywords(token, baseTypes, scope);
- nameEnvironment.findTypes(token, this);
- nameEnvironment.findPackages(token, this);
- }
-
- private void findTypesAndSubpackages(
- char[] token,
- PackageBinding packageBinding) {
-
- char[] qualifiedName =
- CharOperation.concatWith(packageBinding.compoundName, token, '.');
-
- if (token == null || token.length == 0) {
- int length = qualifiedName.length;
- System.arraycopy(
- qualifiedName,
- 0,
- qualifiedName = new char[length + 1],
- 0,
- length);
- qualifiedName[length] = '.';
- }
- nameEnvironment.findTypes(qualifiedName, this);
- nameEnvironment.findPackages(qualifiedName, this);
- }
-
- private void findVariablesAndMethods(
- char[] token,
- Scope scope,
- InvocationSite invocationSite,
- Scope invocationScope) {
-
- if (token == null)
- return;
-
- // Should local variables hide fields from the receiver type or any of its enclosing types?
- // we know its an implicit field/method access... see BlockScope getBinding/getImplicitMethod
-
- boolean staticsOnly = false;
- // need to know if we're in a static context (or inside a constructor)
- int tokenLength = token.length;
-
- ObjectVector localsFound = new ObjectVector();
- ObjectVector fieldsFound = new ObjectVector();
- ObjectVector methodsFound = new ObjectVector();
-
- Scope currentScope = scope;
-
- done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
-
- switch (currentScope.kind) {
-
- case Scope.METHOD_SCOPE :
- // handle the error case inside an explicit constructor call (see MethodScope>>findField)
- MethodScope methodScope = (MethodScope) currentScope;
- staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
-
- case Scope.BLOCK_SCOPE :
- BlockScope blockScope = (BlockScope) currentScope;
-
- next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
- LocalVariableBinding local = blockScope.locals[i];
-
- if (local == null)
- break next;
-
- if (tokenLength > local.name.length)
- continue next;
-
- if (!CharOperation.prefixEquals(token, local.name, false /* ignore case */
- ))
- continue next;
-
- if (local.isSecret())
- continue next;
-
- for (int f = 0; f < localsFound.size; f++) {
- LocalVariableBinding otherLocal =
- (LocalVariableBinding) localsFound.elementAt(f);
- if (CharOperation.equals(otherLocal.name, local.name, true))
- continue next;
- }
- localsFound.add(local);
-
- int relevance = R_DEFAULT;
- relevance += computeRelevanceForCaseMatching(token, local.name);
- relevance += computeRelevanceForExpectingType(local.type);
-
- requestor.acceptLocalVariable(
- local.name,
- local.type == null
- ? NoChar
- : local.type.qualifiedPackageName(),
- local.type == null
- ? local.declaration.type.toString().toCharArray()
- : local.type.qualifiedSourceName(),
- local.modifiers,
- startPosition - offset,
- endPosition - offset,
- relevance);
- }
- break;
-
- case Scope.COMPILATION_UNIT_SCOPE :
- break done1;
- }
- currentScope = currentScope.parent;
- }
-
- currentScope = scope;
-
- done2 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
-
- switch (currentScope.kind) {
-
- case Scope.CLASS_SCOPE :
- ClassScope classScope = (ClassScope) currentScope;
- SourceTypeBinding enclosingType = classScope.referenceContext.binding;
- /* if (tokenLength == 0) { // only search inside the type itself if no prefix was provided
- findFields(token, enclosingType.fields(), classScope, fieldsFound, staticsOnly);
- findMethods(token, enclosingType.methods(), classScope, methodsFound, staticsOnly, false);
- break done;
- } else { */
- findFields(
- token,
- enclosingType,
- classScope,
- fieldsFound,
- localsFound,
- staticsOnly,
- invocationSite,
- invocationScope,
- true);
-
- findMethods(
- token,
- null,
- enclosingType,
- classScope,
- methodsFound,
- staticsOnly,
- false,
- false,
- invocationSite,
- invocationScope,
- true);
- staticsOnly |= enclosingType.isStatic();
- // }
- break;
-
- case Scope.COMPILATION_UNIT_SCOPE :
- break done2;
- }
- currentScope = currentScope.parent;
- }
- }
-
- // Helper method for private void findVariableNames(char[] name, TypeReference type )
- private void findVariableName(char[] token, char[] qualifiedPackageName, char[] qualifiedSourceName, char[] sourceName, char[][] excludeNames, int dim){
- if(sourceName == null || sourceName.length == 0)
- return;
-
- char[] name = null;
-
- // compute variable name for base type
- try{
- nameScanner.setSource(sourceName);
- nameScanner.getNextToken(); // switch (nameScanner.getNextToken()) {
-// case TokenNameint :
-// case TokenNamebyte :
-// case TokenNameshort :
-// case TokenNamechar :
-// case TokenNamelong :
-// case TokenNamefloat :
-// case TokenNamedouble :
-// case TokenNameboolean :
-// if(token != null && token.length != 0)
-// return;
-// name = computeBaseNames(sourceName[0], excludeNames);
-// break;
-// }
- if(name != null) {
- int relevance = R_DEFAULT;
- relevance += computeRelevanceForCaseMatching(token, name);
-
- // accept result
- requestor.acceptVariableName(
- qualifiedPackageName,
- qualifiedSourceName,
- name,
- name,
- startPosition - offset,
- endPosition - offset,
- relevance);
- return;
- }
- } catch(InvalidInputException e){
- }
-
- // compute variable name for non base type
- char[][] names = computeNames(sourceName, dim > 0);
- char[] displayName;
- if (dim > 0){
- int l = qualifiedSourceName.length;
- displayName = new char[l+(2*dim)];
- System.arraycopy(qualifiedSourceName, 0, displayName, 0, l);
- for(int i = 0; i < dim; i++){
- displayName[l+(i*2)] = '[';
- displayName[l+(i*2)+1] = ']';
- }
- } else {
- displayName = qualifiedSourceName;
- }
- next : for(int i = 0 ; i < names.length ; i++){
- name = names[i];
-
- if (!CharOperation.prefixEquals(token, name, false))
- continue next;
-
- // completion must be an identifier (not a keyword, ...).
- try{
- nameScanner.setSource(name);
- if(nameScanner.getNextToken() != TokenNameIdentifier)
- continue next;
- } catch(InvalidInputException e){
- continue next;
- }
-
- int count = 2;
- char[] originalName = name;
- for(int j = 0 ; j < excludeNames.length ; j++){
- if(CharOperation.equals(name, excludeNames[j], false)) {
- name = CharOperation.concat(originalName, String.valueOf(count++).toCharArray());
- j = 0;
- }
- }
-
- int relevance = R_DEFAULT;
- relevance += computeRelevanceForCaseMatching(token, name);
-
- // accept result
- requestor.acceptVariableName(
- qualifiedPackageName,
- displayName,
- name,
- name,
- startPosition - offset,
- endPosition - offset,
- relevance);
- }
- }
-
- private void findVariableNames(char[] name, TypeReference type , char[][] excludeNames){
-
- if(type != null &&
- type.binding != null &&
- type.binding.problemId() == Binding.NoError){
- TypeBinding tb = type.binding;
- findVariableName(
- name,
- tb.leafComponentType().qualifiedPackageName(),
- tb.leafComponentType().qualifiedSourceName(),
- tb.leafComponentType().sourceName(),
- excludeNames,
- type.dimensions());
- }/* else {
- char[][] typeName = type.getTypeName();
- findVariableName(
- name,
- NoChar,
- CharOperation.concatWith(typeName, '.'),
- typeName[typeName.length - 1],
- excludeNames,
- type.dimensions());
- }*/
- }
-
- public AssistParser getParser() {
-
- return parser;
- }
-
- protected void reset() {
-
- super.reset();
- this.knownPkgs = new HashtableOfObject(10);
- this.knownTypes = new HashtableOfObject(10);
- }
-
- private void setSourceRange(int start, int end) {
-
- this.startPosition = start;
- this.endPosition = end + 1;
- }
-
- private char[] computeBaseNames(char firstName, char[][] excludeNames){
- char[] name = new char[]{firstName};
-
- for(int i = 0 ; i < excludeNames.length ; i++){
- if(CharOperation.equals(name, excludeNames[i], false)) {
- name[0]++;
- if(name[0] > 'z')
- name[0] = 'a';
- if(name[0] == firstName)
- return null;
- i = 0;
- }
- }
-
- return name;
- }
- private void computeExpectedTypes(AstNode parent, Scope scope){
- int expectedTypeCount = 0;
- expectedTypes = new TypeBinding[1];
-
- if(parent instanceof AbstractVariableDeclaration) {
- TypeBinding binding = ((AbstractVariableDeclaration)parent).type.binding;
- if(binding != null) {
- expectedTypes[expectedTypeCount++] = binding;
- }
- } else if(parent instanceof Assignment) {
- TypeBinding binding = ((Assignment)parent).lhsType;
- if(binding != null) {
- expectedTypes[expectedTypeCount++] = binding;
- }
- } else if(parent instanceof ReturnStatement) {
- MethodBinding methodBinding = ((AbstractMethodDeclaration) scope.methodScope().referenceContext).binding;
- TypeBinding binding = methodBinding == null ? null : methodBinding.returnType;
- if(binding != null) {
- expectedTypes[expectedTypeCount++] = binding;
- }
- }
-
- System.arraycopy(expectedTypes, 0, expectedTypes = new TypeBinding[expectedTypeCount], 0, expectedTypeCount);
- }
- private char[][] computeNames(char[] sourceName, boolean forArray){
- char[][] names = new char[5][];
- int nameCount = 0;
- boolean previousIsUpperCase = false;
- for(int i = sourceName.length - 1 ; i >= 0 ; i--){
- boolean isUpperCase = Character.isUpperCase(sourceName[i]);
- if(isUpperCase && !previousIsUpperCase){
- char[] name = CharOperation.subarray(sourceName,i,sourceName.length);
- if(name.length > 1){
- if(nameCount == names.length) {
- System.arraycopy(names, 0, names = new char[nameCount * 2][], 0, nameCount);
- }
- name[0] = Character.toLowerCase(name[0]);
-
- if(forArray) {
- int length = name.length;
- if (name[length-1] == 's'){
- System.arraycopy(name, 0, name = new char[length + 2], 0, length);
- name[length] = 'e';
- name[length+1] = 's';
- } else {
- System.arraycopy(name, 0, name = new char[length + 1], 0, length);
- name[length] = 's';
- }
- }
- names[nameCount++] = name;
- }
- }
- previousIsUpperCase = isUpperCase;
- }
- if(nameCount == 0){
- char[] name = CharOperation.toLowerCase(sourceName);
- if(forArray) {
- int length = name.length;
- if (name[length-1] == 's'){
- System.arraycopy(name, 0, name = new char[length + 2], 0, length);
- name[length] = 'e';
- name[length+1] = 's';
- } else {
- System.arraycopy(name, 0, name = new char[length + 1], 0, length);
- name[length] = 's';
- }
- }
- names[nameCount++] = name;
-
- }
- System.arraycopy(names, 0, names = new char[nameCount][], 0, nameCount);
- return names;
- }
-
- private char[] computePrefix(SourceTypeBinding declarationType, SourceTypeBinding invocationType, boolean isStatic){
-
- StringBuffer completion = new StringBuffer(10);
-
- if (isStatic) {
- completion.append(declarationType.sourceName());
-
- } else if (declarationType == invocationType) {
- completion.append(THIS);
-
- } else {
-
- if (!declarationType.isNestedType()) {
-
- completion.append(declarationType.sourceName());
- completion.append('.');
- completion.append(THIS);
-
- } else if (!declarationType.isAnonymousType()) {
-
- completion.append(declarationType.sourceName());
- completion.append('.');
- completion.append(THIS);
-
- }
- }
-
- return completion.toString().toCharArray();
- }
-
- private boolean isEnclosed(ReferenceBinding possibleEnclosingType, ReferenceBinding type){
- if(type.isNestedType()){
- ReferenceBinding enclosing = type.enclosingType();
- while(enclosing != null ){
- if(possibleEnclosingType == enclosing)
- return true;
- enclosing = enclosing.enclosingType();
- }
- }
- return false;
- }
-
-}