### Eclipse Workspace Patch 1.0
#P org.eclipse.jdt.core
Index: codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java,v
retrieving revision 1.200
diff -u -r1.200 CompletionParser.java
--- codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java 20 Oct 2008 15:30:28 -0000 1.200
+++ codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java 14 Jan 2009 12:57:43 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -572,6 +572,15 @@
}
}
}
+public Object becomeSimpleParser() {
+ CompletionScanner completionScanner = (CompletionScanner)this.scanner;
+ int[] parserState = new int[] {this.cursorLocation, completionScanner.cursorLocation};
+
+ this.cursorLocation = Integer.MAX_VALUE;
+ completionScanner.cursorLocation = Integer.MAX_VALUE;
+
+ return parserState;
+}
private void buildMoreAnnotationCompletionContext(MemberValuePair memberValuePair) {
if(this.identifierPtr < 0 || this.identifierLengthPtr < 0 ) return;
@@ -1208,6 +1217,8 @@
}
if(type instanceof CompletionOnSingleTypeReference) {
((CompletionOnSingleTypeReference)type).isConstructorType = true;
+ } else if (type instanceof CompletionOnQualifiedTypeReference) {
+ ((CompletionOnQualifiedTypeReference)type).isConstructorType = true;
}
allocExpr.type = type;
allocExpr.sourceStart = type.sourceStart;
@@ -1227,6 +1238,9 @@
} else {
type = getTypeReference(0);
}
+ if(type instanceof CompletionOnSingleTypeReference) {
+ ((CompletionOnSingleTypeReference)type).isConstructorType = true;
+ }
allocExpr.type = type;
allocExpr.enclosingInstance = this.expressionStack[this.qualifier];
allocExpr.sourceStart = this.intStack[this.intPtr--];
@@ -4539,6 +4553,14 @@
this.cursorLocation = 0;
flushAssistState();
}
+public void restoreAssistParser(Object parserState) {
+ int[] state = (int[]) parserState;
+
+ CompletionScanner completionScanner = (CompletionScanner)this.scanner;
+
+ this.cursorLocation = state[0];
+ completionScanner.cursorLocation = state[1];
+}
/*
* Reset context so as to resume to regular parse loop
* If unable to reset for resuming, answers false.
Index: codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedTypeReference.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedTypeReference.java,v
retrieving revision 1.28
diff -u -r1.28 CompletionOnQualifiedTypeReference.java
--- codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedTypeReference.java 27 Jun 2008 16:03:58 -0000 1.28
+++ codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedTypeReference.java 14 Jan 2009 12:57:42 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -35,6 +35,9 @@
private int kind = K_TYPE;
public char[] completionIdentifier;
+
+ public boolean isConstructorType;
+
public CompletionOnQualifiedTypeReference(char[][] previousIdentifiers, char[] completionIdentifier, long[] positions) {
this(previousIdentifiers, completionIdentifier, positions, K_TYPE);
}
Index: search/org/eclipse/jdt/internal/core/index/DiskIndex.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java,v
retrieving revision 1.67
diff -u -r1.67 DiskIndex.java
--- search/org/eclipse/jdt/internal/core/index/DiskIndex.java 27 Jun 2008 16:04:14 -0000 1.67
+++ search/org/eclipse/jdt/internal/core/index/DiskIndex.java 14 Jan 2009 12:57:45 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -46,7 +46,7 @@
private int streamEnd; // used when writing data from the streamBuffer to the file
char separator = Index.DEFAULT_SEPARATOR;
-public static final String SIGNATURE= "INDEX VERSION 1.125"; //$NON-NLS-1$
+public static final String SIGNATURE= "INDEX VERSION 1.126"; //$NON-NLS-1$
private static final char[] SIGNATURE_CHARS = SIGNATURE.toCharArray();
public static boolean DEBUG = false;
Index: model/org/eclipse/jdt/internal/compiler/SourceElementNotifier.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementNotifier.java,v
retrieving revision 1.5
diff -u -r1.5 SourceElementNotifier.java
--- model/org/eclipse/jdt/internal/compiler/SourceElementNotifier.java 7 Jan 2009 16:29:43 -0000 1.5
+++ model/org/eclipse/jdt/internal/compiler/SourceElementNotifier.java 14 Jan 2009 12:57:44 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008 IBM Corporation and others.
+ * Copyright (c) 2008, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -54,6 +54,7 @@
* An ast visitor that visits local type declarations.
*/
public class LocalDeclarationVisitor extends ASTVisitor {
+ public ImportReference currentPackage;
ArrayList declaringTypes;
public void pushDeclaringType(TypeDeclaration declaringType) {
if (this.declaringTypes == null) {
@@ -71,11 +72,11 @@
return (TypeDeclaration) this.declaringTypes.get(size-1);
}
public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) {
- notifySourceElementRequestor(typeDeclaration, true, peekDeclaringType());
+ notifySourceElementRequestor(typeDeclaration, true, peekDeclaringType(), this.currentPackage);
return false; // don't visit members as this was done during notifySourceElementRequestor(...)
}
public boolean visit(TypeDeclaration typeDeclaration, ClassScope scope) {
- notifySourceElementRequestor(typeDeclaration, true, peekDeclaringType());
+ notifySourceElementRequestor(typeDeclaration, true, peekDeclaringType(), this.currentPackage);
return false; // don't visit members as this was done during notifySourceElementRequestor(...)
}
}
@@ -215,7 +216,7 @@
/*
* Update the bodyStart of the corresponding parse node
*/
-protected void notifySourceElementRequestor(AbstractMethodDeclaration methodDeclaration) {
+protected void notifySourceElementRequestor(AbstractMethodDeclaration methodDeclaration, TypeDeclaration declaringType, ImportReference currentPackage) {
// range check
boolean isInRange =
@@ -288,6 +289,9 @@
methodInfo.typeParameters = getTypeParameterInfos(methodDeclaration.typeParameters());
methodInfo.categories = (char[][]) this.nodesToCategories.get(methodDeclaration);
methodInfo.annotations = methodDeclaration.annotations;
+ methodInfo.declaringPackageName = currentPackage == null ? CharOperation.NO_CHAR : CharOperation.concatWith(currentPackage.tokens, '.');
+ methodInfo.declaringTypeModifiers = declaringType.modifiers;
+ methodInfo.extraFlags = ExtraFlags.getExtraFlags(declaringType);
methodInfo.node = methodDeclaration;
this.requestor.enterConstructor(methodInfo);
}
@@ -394,6 +398,9 @@
this.requestor.enterCompilationUnit();
}
ImportReference currentPackage = parsedUnit.currentPackage;
+ if (this.localDeclarationVisitor != null) {
+ this.localDeclarationVisitor.currentPackage = currentPackage;
+ }
ImportReference[] imports = parsedUnit.imports;
TypeDeclaration[] types = parsedUnit.types;
length =
@@ -429,7 +436,7 @@
notifySourceElementRequestor(importRef, false);
}
} else { // instanceof TypeDeclaration
- notifySourceElementRequestor((TypeDeclaration)node, true, null);
+ notifySourceElementRequestor((TypeDeclaration)node, true, null, currentPackage);
}
}
}
@@ -544,7 +551,7 @@
importReference.modifiers);
}
}
-protected void notifySourceElementRequestor(TypeDeclaration typeDeclaration, boolean notifyTypePresence, TypeDeclaration declaringType) {
+protected void notifySourceElementRequestor(TypeDeclaration typeDeclaration, boolean notifyTypePresence, TypeDeclaration declaringType, ImportReference currentPackage) {
if (CharOperation.equals(TypeConstants.PACKAGE_INFO_NAME, typeDeclaration.name)) return;
@@ -600,6 +607,7 @@
typeInfo.secondary = typeDeclaration.isSecondary();
typeInfo.anonymousMember = typeDeclaration.allocation != null && typeDeclaration.allocation.enclosingInstance != null;
typeInfo.annotations = typeDeclaration.annotations;
+ typeInfo.extraFlags = ExtraFlags.getExtraFlags(typeDeclaration);
typeInfo.node = typeDeclaration;
this.requestor.enterType(typeInfo);
switch (kind) {
@@ -663,11 +671,11 @@
break;
case 1 :
methodIndex++;
- notifySourceElementRequestor(nextMethodDeclaration);
+ notifySourceElementRequestor(nextMethodDeclaration, typeDeclaration, currentPackage);
break;
case 2 :
memberTypeIndex++;
- notifySourceElementRequestor(nextMemberDeclaration, true, null);
+ notifySourceElementRequestor(nextMemberDeclaration, true, null, currentPackage);
}
}
if (notifyTypePresence){
Index: model/org/eclipse/jdt/internal/compiler/ISourceElementRequestor.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/ISourceElementRequestor.java,v
retrieving revision 1.24
diff -u -r1.24 ISourceElementRequestor.java
--- model/org/eclipse/jdt/internal/compiler/ISourceElementRequestor.java 7 Jan 2009 16:29:43 -0000 1.24
+++ model/org/eclipse/jdt/internal/compiler/ISourceElementRequestor.java 14 Jan 2009 12:57:44 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -59,6 +59,7 @@
public boolean secondary;
public boolean anonymousMember;
public Annotation[] annotations;
+ public int extraFlags;
public TypeDeclaration node;
public HashMap childrenCategories = new HashMap();
}
@@ -87,6 +88,9 @@
public TypeParameterInfo[] typeParameters;
public char[][] categories;
public Annotation[] annotations;
+ public char[] declaringPackageName;
+ public int declaringTypeModifiers;
+ public int extraFlags;
public AbstractMethodDeclaration node;
}
Index: search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexerRequestor.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexerRequestor.java,v
retrieving revision 1.47
diff -u -r1.47 SourceIndexerRequestor.java
--- search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexerRequestor.java 27 Jun 2008 16:03:49 -0000 1.47
+++ search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexerRequestor.java 14 Jan 2009 12:57:46 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -12,7 +12,9 @@
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.ExtraFlags;
import org.eclipse.jdt.internal.compiler.ISourceElementRequestor;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.ImportReference;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
@@ -130,6 +132,29 @@
public void acceptUnknownReference(char[] name, int sourcePosition) {
this.indexer.addNameReference(name);
}
+
+private void addDefaultConstructorIfNecessary(TypeInfo typeInfo) {
+ boolean hasConstructor = false;
+
+ TypeDeclaration typeDeclaration = typeInfo.node;
+ AbstractMethodDeclaration[] methods = typeDeclaration.methods;
+ int methodCounter = methods == null ? 0 : methods.length;
+ done : for (int i = 0; i < methodCounter; i++) {
+ AbstractMethodDeclaration method = methods[i];
+ if (method.isConstructor() && !method.isDefaultConstructor()) {
+ hasConstructor = true;
+ break done;
+ }
+ }
+
+ if (!hasConstructor) {
+ this.indexer.addDefaultConstructorDeclaration(
+ typeInfo.name,
+ this.packageName == null ? CharOperation.NO_CHAR : this.packageName,
+ typeInfo.modifiers,
+ getMoreExtraFlags(typeInfo.extraFlags));
+ }
+}
/*
* Rebuild the proper qualification for the current source type:
*
@@ -153,6 +178,7 @@
typeNames = enclosingTypeNames();
}
this.indexer.addAnnotationTypeDeclaration(typeInfo.modifiers, this.packageName, typeInfo.name, typeNames, typeInfo.secondary);
+ addDefaultConstructorIfNecessary(typeInfo);
pushTypeName(typeInfo.name);
}
@@ -187,6 +213,7 @@
}
}
this.indexer.addClassDeclaration(typeInfo.modifiers, this.packageName, typeInfo.name, typeNames, typeInfo.superclass, typeInfo.superinterfaces, typeParameterSignatures, typeInfo.secondary);
+ addDefaultConstructorIfNecessary(typeInfo);
pushTypeName(typeInfo.name);
}
/**
@@ -199,7 +226,18 @@
* @see ISourceElementRequestor#enterConstructor(ISourceElementRequestor.MethodInfo)
*/
public void enterConstructor(MethodInfo methodInfo) {
- this.indexer.addConstructorDeclaration(methodInfo.name, methodInfo.parameterTypes, methodInfo.exceptionTypes);
+ int argCount = methodInfo.parameterTypes == null ? 0 : methodInfo.parameterTypes.length;
+ this.indexer.addConstructorDeclaration(
+ methodInfo.name,
+ argCount,
+ null,
+ methodInfo.parameterTypes,
+ methodInfo.parameterNames,
+ methodInfo.modifiers,
+ methodInfo.declaringPackageName,
+ methodInfo.declaringTypeModifiers,
+ methodInfo.exceptionTypes,
+ getMoreExtraFlags(methodInfo.extraFlags));
this.methodDepth++;
}
private void enterEnum(TypeInfo typeInfo) {
@@ -217,6 +255,7 @@
}
char[] superclass = typeInfo.superclass == null ? CharOperation.concatWith(TypeConstants.JAVA_LANG_ENUM, '.'): typeInfo.superclass;
this.indexer.addEnumDeclaration(typeInfo.modifiers, this.packageName, typeInfo.name, typeNames, superclass, typeInfo.superinterfaces, typeInfo.secondary);
+ addDefaultConstructorIfNecessary(typeInfo);
pushTypeName(typeInfo.name);
}
/**
@@ -255,6 +294,7 @@
}
}
this.indexer.addInterfaceDeclaration(typeInfo.modifiers, this.packageName, typeInfo.name, typeNames, typeInfo.superinterfaces, typeParameterSignatures, typeInfo.secondary);
+ addDefaultConstructorIfNecessary(typeInfo);
pushTypeName(typeInfo.name);
}
/**
@@ -353,6 +393,12 @@
}
return CharOperation.subarray(typeName, lastDot + 1, lastGenericStart);
}
+private int getMoreExtraFlags(int extraFlags) {
+ if (this.methodDepth > 0) {
+ extraFlags |= ExtraFlags.IsLocalType;
+ }
+ return extraFlags;
+}
public void popTypeName() {
if (this.depth > 0) {
this.enclosingTypeNames[--this.depth] = null;
Index: search/org/eclipse/jdt/internal/core/search/indexing/AbstractIndexer.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AbstractIndexer.java,v
retrieving revision 1.40
diff -u -r1.40 AbstractIndexer.java
--- search/org/eclipse/jdt/internal/core/search/indexing/AbstractIndexer.java 27 Jun 2008 16:03:49 -0000 1.40
+++ search/org/eclipse/jdt/internal/core/search/indexing/AbstractIndexer.java 14 Jan 2009 12:57:45 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -71,10 +71,30 @@
typeName = CharOperation.subarray(typeName, 0, genericStart);
return typeName;
}
- public void addConstructorDeclaration(char[] typeName, char[][] parameterTypes, char[][] exceptionTypes) {
- int argCount = parameterTypes == null ? 0 : parameterTypes.length;
- addIndexEntry(CONSTRUCTOR_DECL, ConstructorPattern.createIndexKey(CharOperation.lastSegment(typeName,'.'), argCount));
-
+ public void addConstructorDeclaration(
+ char[] typeName,
+ int argCount,
+ char[] signature,
+ char[][] parameterTypes,
+ char[][] parameterNames,
+ int modifiers,
+ char[] packageName,
+ int typeModifiers,
+ char[][] exceptionTypes,
+ int extraFlags) {
+ addIndexEntry(
+ CONSTRUCTOR_DECL,
+ ConstructorPattern.createDeclarationIndexKey(
+ typeName,
+ argCount,
+ signature,
+ parameterTypes,
+ parameterNames,
+ modifiers,
+ packageName,
+ typeModifiers,
+ extraFlags));
+
if (parameterTypes != null) {
for (int i = 0; i < argCount; i++)
addTypeReference(parameterTypes[i]);
@@ -91,6 +111,13 @@
if (innermostTypeName != simpleTypeName)
addIndexEntry(CONSTRUCTOR_REF, ConstructorPattern.createIndexKey(innermostTypeName, argCount));
}
+ public void addDefaultConstructorDeclaration(
+ char[] typeName,
+ char[] packageName,
+ int typeModifiers,
+ int extraFlags) {
+ addIndexEntry(CONSTRUCTOR_DECL, ConstructorPattern.createDefaultDeclarationIndexKey(CharOperation.lastSegment(typeName,'.'), packageName, typeModifiers, extraFlags));
+ }
public void addEnumDeclaration(int modifiers, char[] packageName, char[] name, char[][] enclosingTypeNames, char[] superclass, char[][] superinterfaces, boolean secondary) {
addTypeDeclaration(modifiers, packageName, name, enclosingTypeNames, secondary);
Index: search/org/eclipse/jdt/internal/core/search/indexing/IIndexConstants.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IIndexConstants.java,v
retrieving revision 1.37
diff -u -r1.37 IIndexConstants.java
--- search/org/eclipse/jdt/internal/core/search/indexing/IIndexConstants.java 27 Jun 2008 16:03:49 -0000 1.37
+++ search/org/eclipse/jdt/internal/core/search/indexing/IIndexConstants.java 14 Jan 2009 12:57:45 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -29,6 +29,7 @@
new char[][] { new char[] {'/', '0'}, new char[] {'/', '1'}, new char[] {'/', '2'}, new char[] {'/', '3'}, new char[] {'/', '4'},
new char[] {'/', '5'}, new char[] {'/', '6'}, new char[] {'/', '7'}, new char[] {'/', '8'}, new char[] {'/', '9'}
};
+ char[] DEFAULT_CONSTRUCTOR = new char[]{'/', '#'};
char CLASS_SUFFIX = 'C';
char INTERFACE_SUFFIX = 'I';
char ENUM_SUFFIX = 'E';
@@ -38,6 +39,7 @@
char CLASS_AND_INTERFACE_SUFFIX = IJavaSearchConstants.CLASS_AND_INTERFACE;
char INTERFACE_AND_ANNOTATION_SUFFIX = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
char SEPARATOR= '/';
+ char PARAMETER_SEPARATOR= ',';
char SECONDARY_SUFFIX = 'S';
char[] ONE_STAR = new char[] {'*'};
Index: search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java,v
retrieving revision 1.68
diff -u -r1.68 BinaryIndexer.java
--- search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java 27 Jun 2008 16:03:49 -0000 1.68
+++ search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java 14 Jan 2009 12:57:45 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -14,6 +14,7 @@
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.search.SearchDocument;
+import org.eclipse.jdt.internal.compiler.ExtraFlags;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
@@ -700,9 +701,12 @@
if (tagBits != 0) {
addBinaryStandardAnnotations(tagBits);
}
+
+ int extraFlags = ExtraFlags.getExtraFlags(reader);
// first reference all methods declarations and field declarations
MethodInfo[] methods = (MethodInfo[]) reader.getMethods();
+ boolean noConstructor = true;
if (methods != null) {
for (int i = 0, max = methods.length; i < max; i++) {
MethodInfo method = methods[i];
@@ -712,7 +716,26 @@
char[] returnType = decodeReturnType(descriptor);
char[][] exceptionTypes = replace('/', '.', method.getExceptionTypeNames());
if (isConstructor) {
- addConstructorDeclaration(className, parameterTypes, exceptionTypes);
+ noConstructor = false;
+ char[] signature = method.getGenericSignature();
+ if (signature == null) {
+ if (reader.isNestedType() && ((modifiers & ClassFileConstants.AccStatic) == 0)) {
+ signature = removeFirstSyntheticParameter(descriptor);
+ } else {
+ signature = descriptor;
+ }
+ }
+ addConstructorDeclaration(
+ name,
+ parameterTypes == null ? 0 : parameterTypes.length,
+ signature,
+ parameterTypes,
+ method.getArgumentNames(),
+ method.getModifiers(),
+ packageName,
+ modifiers,
+ exceptionTypes,
+ extraFlags);
} else {
if (!method.isClinit()) {
addMethodDeclaration(method.getSelector(), parameterTypes, returnType, exceptionTypes);
@@ -732,6 +755,9 @@
}
}
}
+ if (noConstructor) {
+ addDefaultConstructorDeclaration(className, packageName, modifiers, extraFlags);
+ }
FieldInfo[] fields = (FieldInfo[]) reader.getFields();
if (fields != null) {
for (int i = 0, max = fields.length; i < max; i++) {
@@ -767,6 +793,23 @@
Util.log(IStatus.WARNING, "The Java indexing could not index " + this.document.getPath() + ". This .class file doesn't follow the class file format specification. Please report this issue against the .class file vendor"); //$NON-NLS-1$ //$NON-NLS-2$
}
}
+
+ private char[] removeFirstSyntheticParameter(char[] descriptor) {
+ if (descriptor == null) return null;
+ if (descriptor.length < 3) return descriptor;
+ if (descriptor[0] != '(') return descriptor;
+ if (descriptor[1] != ')') {
+ // remove the first synthetic parameter
+ int start = Util.scanTypeSignature(descriptor, 1) + 1;
+ int length = descriptor.length - start;
+ char[] signature = new char[length + 1];
+ signature[0] = descriptor[0];
+ System.arraycopy(descriptor, start, signature, 1, length);
+ return signature;
+ } else {
+ return descriptor;
+ }
+ }
/*
* Modify the array by replacing all occurences of toBeReplaced with newChar
*/
Index: codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java,v
retrieving revision 1.383
diff -u -r1.383 CompletionEngine.java
--- codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java 8 Jan 2009 20:51:06 -0000 1.383
+++ codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java 14 Jan 2009 12:57:41 -0000
@@ -40,6 +40,7 @@
import org.eclipse.jdt.internal.codeassist.impl.Keywords;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
+import org.eclipse.jdt.internal.compiler.ExtraFlags;
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.env.*;
@@ -60,12 +61,14 @@
import org.eclipse.jdt.internal.core.BasicCompilationUnit;
import org.eclipse.jdt.internal.core.INamingRequestor;
import org.eclipse.jdt.internal.core.InternalNamingConventions;
+import org.eclipse.jdt.internal.core.JavaModelManager;
import org.eclipse.jdt.internal.core.SourceMethod;
import org.eclipse.jdt.internal.core.SourceMethodElementInfo;
import org.eclipse.jdt.internal.core.SourceType;
import org.eclipse.jdt.internal.core.BinaryTypeConverter;
import org.eclipse.jdt.internal.core.SearchableEnvironment;
import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
+import org.eclipse.jdt.internal.core.search.matching.JavaSearchNameEnvironment;
import org.eclipse.jdt.internal.core.util.Messages;
/**
@@ -77,6 +80,57 @@
extends Engine
implements ISearchRequestor, TypeConstants , TerminalTokens , RelevanceConstants, SuffixConstants {
+ private static class AcceptedConstructor {
+ public int modifiers;
+ public char[] simpleTypeName;
+ public int parameterCount;
+ public char[] signature;
+ public char[][] parameterTypes;
+ public char[][] parameterNames;
+ public int typeModifiers;
+ public char[] packageName;
+ public int extraFlags;
+ public int accessibility;
+ public boolean proposeType = false;
+ public boolean proposeConstructor = false;
+ public char[] fullyQualifiedName = null;
+
+ public boolean mustBeQualified = false;
+
+ public AcceptedConstructor(
+ int modifiers,
+ char[] simpleTypeName,
+ int parameterCount,
+ char[] signature,
+ char[][] parameterTypes,
+ char[][] parameterNames,
+ int typeModifiers,
+ char[] packageName,
+ int extraFlags,
+ int accessibility) {
+ this.modifiers = modifiers;
+ this.simpleTypeName = simpleTypeName;
+ this.parameterCount = parameterCount;
+ this.signature = signature;
+ this.parameterTypes = parameterTypes;
+ this.parameterNames = parameterNames;
+ this.typeModifiers = typeModifiers;
+ this.packageName = packageName;
+ this.extraFlags = extraFlags;
+ this.accessibility = accessibility;
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append('{');
+ buffer.append(this.packageName);
+ buffer.append(',');
+ buffer.append(this.simpleTypeName);
+ buffer.append('}');
+ return buffer.toString();
+ }
+ }
+
private static class AcceptedType {
public char[] packageName;
public char[] simpleTypeName;
@@ -226,7 +280,40 @@
this.checkProblems = false;
}
}
+
+ public static char[] createBindingKey(char[] packageName, char[] typeName) {
+ char[] signature = createTypeSignature(packageName, typeName);
+ CharOperation.replace(signature, '.', '/');
+ return signature;
+ }
+ public static char[][] createDefaultParameterNames(int length) {
+ char[][] parameters;
+ switch (length) {
+ case 0 :
+ parameters = new char[length][];
+ break;
+ case 1 :
+ parameters = ARGS1;
+ break;
+ case 2 :
+ parameters = ARGS2;
+ break;
+ case 3 :
+ parameters = ARGS3;
+ break;
+ case 4 :
+ parameters = ARGS4;
+ break;
+ default :
+ parameters = new char[length][];
+ for (int i = 0; i < length; i++) {
+ parameters[i] = CharOperation.concat(ARG, String.valueOf(i).toCharArray());
+ }
+ break;
+ }
+ return parameters;
+ }
public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnTypeSignature) {
char[][] parameterTypeSignature = new char[parameterTypeNames.length][];
for (int i = 0; i < parameterTypeSignature.length; i++) {
@@ -302,12 +389,44 @@
result = CharOperation.replaceOnCopy(result, '/', '.');
return result;
}
+
+ private static boolean hasStaticMemberTypes(ReferenceBinding typeBinding, SourceTypeBinding invocationType, CompilationUnitScope unitScope) {
+ ReferenceBinding[] memberTypes = typeBinding.memberTypes();
+ int length = memberTypes == null ? 0 : memberTypes.length;
+ next : for (int i = 0; i < length; i++) {
+ ReferenceBinding memberType = memberTypes[i];
+ if (invocationType != null && !memberType.canBeSeenBy(typeBinding, invocationType)) {
+ continue next;
+ } else if(invocationType == null && !memberType.canBeSeenBy(unitScope.fPackage)) {
+ continue next;
+ }
+
+ if ((memberType.modifiers & ClassFileConstants.AccStatic) != 0) {
+ return true;
+ }
+ }
+ return false;
+ }
public HashtableOfObject typeCache;
+ public int openedBinaryTypes; // used during InternalCompletionProposal#findConstructorParameterNames()
public static boolean DEBUG = false;
public static boolean PERF = false;
- private final static int CHECK_CANCEL_FREQUENCY_IN_FIND_TYPES = 50;
+ private static final char[] KNOWN_TYPE_WITH_UNKNOWN_CONSTRUCTORS = new char[]{};
+ private static final char[] KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS = new char[]{};
+
+ private static final char[] ARG = "arg".toCharArray(); //$NON-NLS-1$
+ private static final char[] ARG0 = "arg0".toCharArray(); //$NON-NLS-1$
+ private static final char[] ARG1 = "arg1".toCharArray(); //$NON-NLS-1$
+ private static final char[] ARG2 = "arg2".toCharArray(); //$NON-NLS-1$
+ private static final char[] ARG3 = "arg3".toCharArray(); //$NON-NLS-1$
+ private static final char[][] ARGS1 = new char[][]{ARG0};
+ private static final char[][] ARGS2 = new char[][]{ARG0, ARG1};
+ private static final char[][] ARGS3 = new char[][]{ARG0, ARG1, ARG2};
+ private static final char[][] ARGS4 = new char[][]{ARG0, ARG1, ARG2, ARG3};
+
+ private final static int CHECK_CANCEL_FREQUENCY = 50;
// temporary constants to quickly disabled polish features if necessary
public final static boolean NO_TYPE_COMPLETION_ON_EMPTY_TOKEN = false;
@@ -323,6 +442,7 @@
private final static char[] VALUE = "value".toCharArray(); //$NON-NLS-1$
private final static char[] EXTENDS = "extends".toCharArray(); //$NON-NLS-1$
private final static char[] SUPER = "super".toCharArray(); //$NON-NLS-1$
+ private final static char[] DEFAULT_CONSTRUCTOR_SIGNATURE = "()V".toCharArray(); //$NON-NLS-1$
private final static char[] DOT = ".".toCharArray(); //$NON-NLS-1$
@@ -374,6 +494,7 @@
CompletionRequestor requestor;
CompletionProblemFactory problemFactory;
ProblemReporter problemReporter;
+ private JavaSearchNameEnvironment noCacheNameEnvironment;
char[] source;
char[] completionToken;
char[] qualifiedCompletionToken;
@@ -459,6 +580,9 @@
private int foundTypesCount;
private ObjectVector acceptedTypes;
+
+ private int foundConstructorsCount;
+ private ObjectVector acceptedConstructors;
/**
* The CompletionEngine is responsible for computing source completions.
@@ -489,6 +613,7 @@
this.requestor = requestor;
this.nameEnvironment = nameEnvironment;
this.typeCache = new HashtableOfObject(5);
+ this.openedBinaryTypes = 0;
this.problemFactory = new CompletionProblemFactory(Locale.getDefault());
this.problemReporter = new ProblemReporter(
@@ -511,6 +636,391 @@
this.owner = owner;
this.monitor = monitor;
}
+
+ public void acceptConstructor(
+ int modifiers,
+ char[] simpleTypeName,
+ int parameterCount,
+ char[] signature,
+ char[][] parameterTypes,
+ char[][] parameterNames,
+ int typeModifiers,
+ char[] packageName,
+ int extraFlags,
+ String path,
+ AccessRestriction accessRestriction) {
+
+ // does not check cancellation for every types to avoid performance loss
+ if ((this.foundConstructorsCount % (CHECK_CANCEL_FREQUENCY)) == 0) checkCancel();
+ this.foundConstructorsCount++;
+
+ if ((typeModifiers & ClassFileConstants.AccEnum) != 0) return;
+
+ if (this.options.checkDeprecation && (typeModifiers & ClassFileConstants.AccDeprecated) != 0) return;
+
+ if (this.options.checkVisibility) {
+ if((typeModifiers & ClassFileConstants.AccPublic) == 0) {
+ if((typeModifiers & ClassFileConstants.AccPrivate) != 0) return;
+
+ if (this.currentPackageName == null) {
+ initializePackageCache();
+ }
+
+ if(!CharOperation.equals(packageName, this.currentPackageName)) return;
+ }
+ }
+
+ int accessibility = IAccessRule.K_ACCESSIBLE;
+ if(accessRestriction != null) {
+ switch (accessRestriction.getProblemId()) {
+ case IProblem.ForbiddenReference:
+ if (this.options.checkForbiddenReference) {
+ return;
+ }
+ accessibility = IAccessRule.K_NON_ACCESSIBLE;
+ break;
+ case IProblem.DiscouragedReference:
+ if (this.options.checkDiscouragedReference) {
+ return;
+ }
+ accessibility = IAccessRule.K_DISCOURAGED;
+ break;
+ }
+ }
+
+ if(this.acceptedConstructors == null) {
+ this.acceptedConstructors = new ObjectVector();
+ }
+ this.acceptedConstructors.add(
+ new AcceptedConstructor(
+ modifiers,
+ simpleTypeName,
+ parameterCount,
+ signature,
+ parameterTypes,
+ parameterNames,
+ typeModifiers,
+ packageName,
+ extraFlags,
+ accessibility));
+ }
+
+ private void acceptConstructors(Scope scope) {
+ final boolean DEFER_QUALIFIED_PROPOSALS = false;
+
+ this.checkCancel();
+
+ if(this.acceptedConstructors == null) return;
+
+ int length = this.acceptedConstructors.size();
+
+ if(length == 0) return;
+
+ HashtableOfObject onDemandFound = new HashtableOfObject();
+
+ ArrayList deferredProposals = new ArrayList();
+
+ try {
+ next : for (int i = 0; i < length; i++) {
+
+ // does not check cancellation for every types to avoid performance loss
+ if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
+
+ AcceptedConstructor acceptedConstructor = (AcceptedConstructor)this.acceptedConstructors.elementAt(i);
+ final int typeModifiers = acceptedConstructor.typeModifiers;
+ final char[] packageName = acceptedConstructor.packageName;
+ final char[] simpleTypeName = acceptedConstructor.simpleTypeName;
+ final int modifiers = acceptedConstructor.modifiers;
+ final int parameterCount = acceptedConstructor.parameterCount;
+ final char[] signature = acceptedConstructor.signature;
+ final char[][] parameterTypes = acceptedConstructor.parameterTypes;
+ final char[][] parameterNames = acceptedConstructor.parameterNames;
+ final int extraFlags = acceptedConstructor.extraFlags;
+ final int accessibility = acceptedConstructor.accessibility;
+
+ boolean proposeType = (extraFlags & ExtraFlags.HasNonPrivateStaticMemberTypes) != 0;
+
+ char[] fullyQualifiedName = CharOperation.concat(packageName, simpleTypeName, '.');
+
+ Object knownTypeKind = this.knownTypes.get(fullyQualifiedName);
+ if (knownTypeKind != null) {
+ if (knownTypeKind == KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS) {
+ // the type and its constructors are already accepted
+ continue next;
+ }
+ // this type is already accepted
+ proposeType = false;
+ } else {
+ this.knownTypes.put(fullyQualifiedName, KNOWN_TYPE_WITH_UNKNOWN_CONSTRUCTORS);
+ }
+
+ boolean proposeConstructor = true;
+
+ if (this.options.checkVisibility) {
+ if((modifiers & ClassFileConstants.AccPublic) == 0) {
+ if((modifiers & ClassFileConstants.AccPrivate) != 0) {
+ if (!proposeType) continue next;
+ proposeConstructor = false;
+ } else {
+ if (this.currentPackageName == null) {
+ initializePackageCache();
+ }
+
+ if(!CharOperation.equals(packageName, this.currentPackageName)) {
+ if (!proposeType) continue next;
+ proposeConstructor = false;
+ }
+ }
+ }
+ }
+
+ acceptedConstructor.fullyQualifiedName = fullyQualifiedName;
+ acceptedConstructor.proposeType = proposeType;
+ acceptedConstructor.proposeConstructor = proposeConstructor;
+
+
+ if(!this.importCachesInitialized) {
+ initializeImportCaches();
+ }
+
+ for (int j = 0; j < this.importCacheCount; j++) {
+ char[][] importName = this.importsCache[j];
+ if(CharOperation.equals(simpleTypeName, importName[0])) {
+ if (proposeType) {
+ proposeType(
+ packageName,
+ simpleTypeName,
+ typeModifiers,
+ accessibility,
+ simpleTypeName,
+ fullyQualifiedName,
+ !CharOperation.equals(fullyQualifiedName, importName[1]),
+ scope);
+ }
+
+ if (proposeConstructor && !Flags.isEnum(typeModifiers)) {
+ boolean isQualified = !CharOperation.equals(fullyQualifiedName, importName[1]);
+ if (!isQualified) {
+ proposeConstructor(
+ simpleTypeName,
+ parameterCount,
+ signature,
+ parameterTypes,
+ parameterNames,
+ modifiers,
+ packageName,
+ typeModifiers,
+ accessibility,
+ simpleTypeName,
+ fullyQualifiedName,
+ isQualified,
+ scope,
+ extraFlags);
+ } else {
+ acceptedConstructor.mustBeQualified = true;
+ if (DEFER_QUALIFIED_PROPOSALS) {
+ deferredProposals.add(acceptedConstructor);
+ } else {
+ proposeConstructor(acceptedConstructor, scope);
+ }
+ }
+ }
+ continue next;
+ }
+ }
+
+
+ if (CharOperation.equals(this.currentPackageName, packageName)) {
+ if (proposeType) {
+ proposeType(
+ packageName,
+ simpleTypeName,
+ typeModifiers,
+ accessibility,
+ simpleTypeName,
+ fullyQualifiedName,
+ false,
+ scope);
+ }
+
+ if (proposeConstructor && !Flags.isEnum(typeModifiers)) {
+ proposeConstructor(
+ simpleTypeName,
+ parameterCount,
+ signature,
+ parameterTypes,
+ parameterNames,
+ modifiers,
+ packageName,
+ typeModifiers,
+ accessibility,
+ simpleTypeName,
+ fullyQualifiedName,
+ false,
+ scope,
+ extraFlags);
+ }
+ continue next;
+ } else {
+ char[] fullyQualifiedEnclosingTypeOrPackageName = null;
+
+ AcceptedConstructor foundConstructor = null;
+ if((foundConstructor = (AcceptedConstructor)onDemandFound.get(simpleTypeName)) == null) {
+ for (int j = 0; j < this.onDemandImportCacheCount; j++) {
+ ImportBinding importBinding = this.onDemandImportsCache[j];
+
+ char[][] importName = importBinding.compoundName;
+ char[] importFlatName = CharOperation.concatWith(importName, '.');
+
+ if(fullyQualifiedEnclosingTypeOrPackageName == null) {
+ fullyQualifiedEnclosingTypeOrPackageName = packageName;
+ }
+ if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
+ if(importBinding.isStatic()) {
+ if((typeModifiers & ClassFileConstants.AccStatic) != 0) {
+ onDemandFound.put(
+ simpleTypeName,
+ acceptedConstructor);
+ continue next;
+ }
+ } else {
+ onDemandFound.put(
+ simpleTypeName,
+ acceptedConstructor);
+ continue next;
+ }
+ }
+ }
+ } else if(!foundConstructor.mustBeQualified){
+ done : for (int j = 0; j < this.onDemandImportCacheCount; j++) {
+ ImportBinding importBinding = this.onDemandImportsCache[j];
+
+ char[][] importName = importBinding.compoundName;
+ char[] importFlatName = CharOperation.concatWith(importName, '.');
+
+ if(fullyQualifiedEnclosingTypeOrPackageName == null) {
+ fullyQualifiedEnclosingTypeOrPackageName = packageName;
+ }
+ if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
+ if(importBinding.isStatic()) {
+ if((typeModifiers & ClassFileConstants.AccStatic) != 0) {
+ foundConstructor.mustBeQualified = true;
+ break done;
+ }
+ } else {
+ foundConstructor.mustBeQualified = true;
+ break done;
+ }
+ }
+ }
+ }
+ if (proposeType) {
+ proposeType(
+ packageName,
+ simpleTypeName,
+ typeModifiers,
+ accessibility,
+ simpleTypeName,
+ fullyQualifiedName,
+ true,
+ scope);
+ }
+
+ if (proposeConstructor && !Flags.isEnum(typeModifiers)) {
+ acceptedConstructor.mustBeQualified = true;
+ if (DEFER_QUALIFIED_PROPOSALS) {
+ deferredProposals.add(acceptedConstructor);
+ } else {
+ proposeConstructor(acceptedConstructor, scope);
+ }
+ }
+ }
+ }
+
+ char[][] keys = onDemandFound.keyTable;
+ Object[] values = onDemandFound.valueTable;
+ int max = keys.length;
+ for (int i = 0; i < max; i++) {
+
+ // does not check cancellation for every types to avoid performance loss
+ if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
+
+ if(keys[i] != null) {
+ AcceptedConstructor value = (AcceptedConstructor) values[i];
+ if(value != null) {
+ if (value.proposeType) {
+ proposeType(
+ value.packageName,
+ value.simpleTypeName,
+ value.typeModifiers,
+ value.accessibility,
+ value.simpleTypeName,
+ value.fullyQualifiedName,
+ value.mustBeQualified,
+ scope);
+ }
+
+ if (value.proposeConstructor && !Flags.isEnum(value.modifiers)) {
+ if (!value.mustBeQualified) {
+ proposeConstructor(
+ value.simpleTypeName,
+ value.parameterCount,
+ value.signature,
+ value.parameterTypes,
+ value.parameterNames,
+ value.modifiers,
+ value.packageName,
+ value.typeModifiers,
+ value.accessibility,
+ value.simpleTypeName,
+ value.fullyQualifiedName,
+ value.mustBeQualified,
+ scope,
+ value.extraFlags);
+ } else {
+ if (DEFER_QUALIFIED_PROPOSALS) {
+ deferredProposals.add(value);
+ } else {
+ proposeConstructor(value, scope);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (DEFER_QUALIFIED_PROPOSALS) {
+ int size = deferredProposals.size();
+ for (int i = 0; i < size; i++) {
+
+ // does not check cancellation for every types to avoid performance loss
+ if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
+
+ AcceptedConstructor deferredProposal = (AcceptedConstructor)deferredProposals.get(i);
+
+ if (deferredProposal.proposeConstructor) {
+ proposeConstructor(
+ deferredProposal.simpleTypeName,
+ deferredProposal.parameterCount,
+ deferredProposal.signature,
+ deferredProposal.parameterTypes,
+ deferredProposal.parameterNames,
+ deferredProposal.modifiers,
+ deferredProposal.packageName,
+ deferredProposal.typeModifiers,
+ deferredProposal.accessibility,
+ deferredProposal.simpleTypeName,
+ deferredProposal.fullyQualifiedName,
+ deferredProposal.mustBeQualified,
+ scope,
+ deferredProposal.extraFlags);
+ }
+ }
+ }
+ } finally {
+ this.acceptedTypes = null; // reset
+ }
+ }
/**
* One result of the search consists of a new package.
@@ -577,7 +1087,7 @@
AccessRestriction accessRestriction) {
// does not check cancellation for every types to avoid performance loss
- if ((this.foundTypesCount % CHECK_CANCEL_FREQUENCY_IN_FIND_TYPES) == 0) checkCancel();
+ if ((this.foundTypesCount % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
this.foundTypesCount++;
if (this.options.checkDeprecation && (modifiers & ClassFileConstants.AccDeprecated) != 0) return;
@@ -630,7 +1140,7 @@
next : for (int i = 0; i < length; i++) {
// does not check cancellation for every types to avoid performance loss
- if ((i % CHECK_CANCEL_FREQUENCY_IN_FIND_TYPES) == 0) checkCancel();
+ if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
AcceptedType acceptedType = (AcceptedType)this.acceptedTypes.elementAt(i);
char[] packageName = acceptedType.packageName;
@@ -652,7 +1162,7 @@
if (this.knownTypes.containsKey(fullyQualifiedName)) continue next;
- this.knownTypes.put(fullyQualifiedName, this);
+ this.knownTypes.put(fullyQualifiedName, KNOWN_TYPE_WITH_UNKNOWN_CONSTRUCTORS);
if (this.resolvingImports) {
if(this.compilerOptions.complianceLevel >= ClassFileConstants.JDK1_4 && packageName.length == 0) {
@@ -808,6 +1318,7 @@
Object[] values = onDemandFound.valueTable;
int max = keys.length;
for (int i = 0; i < max; i++) {
+ if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
if(keys[i] != null) {
AcceptedType value = (AcceptedType) values[i];
if(value != null) {
@@ -2448,6 +2959,7 @@
this.assistNodeIsClass = ref.isClass();
this.assistNodeIsException = ref.isException();
this.assistNodeIsInterface = ref.isInterface();
+ this.assistNodeIsConstructor = ref.isConstructorType;
this.assistNodeIsSuperType = ref.isSuperType();
this.completionToken = ref.completionIdentifier;
@@ -3201,7 +3713,7 @@
TypeBinding caughtException = catchArguments[i].type.resolvedType;
if (caughtException != null) {
addForbiddenBindings(caughtException);
- this.knownTypes.put(CharOperation.concat(caughtException.qualifiedPackageName(), caughtException.qualifiedSourceName(), '.'), this);
+ this.knownTypes.put(CharOperation.concat(caughtException.qualifiedPackageName(), caughtException.qualifiedSourceName(), '.'), KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS);
}
}
this.forbbidenBindingsFilter = SUBTYPE;
@@ -3943,45 +4455,121 @@
}
}
private void findAnonymousType(
+ ReferenceBinding currentType,
+ TypeBinding[] argTypes,
+ Scope scope,
+ InvocationSite invocationSite) {
+
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+
+ findAnonymousType(currentType, argTypes, scope, invocationSite, true, false, relevance);
+ }
+ private void findAnonymousType(
ReferenceBinding currentType,
TypeBinding[] argTypes,
Scope scope,
- InvocationSite invocationSite) {
+ InvocationSite invocationSite,
+ boolean exactMatch,
+ boolean isQualified,
+ int relevance) {
if (currentType.isInterface()) {
char[] completion = CharOperation.NO_CHAR;
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+ char[] typeCompletion = null;
+ if (!exactMatch) {
+ typeCompletion =
+ isQualified ?
+ CharOperation.concat(currentType.qualifiedPackageName(), currentType.qualifiedSourceName(), '.') :
+ currentType.sourceName();
+ if (this.source != null
+ && this.source.length > this.endPosition
+ && this.source[this.endPosition] == '(') {
+ completion = CharOperation.NO_CHAR;
+ } else {
+ completion = new char[] { '(', ')' };
+ }
+ }
this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(currentType));
- proposal.setDeclarationKey(currentType.computeUniqueKey());
- proposal.setSignature(
- createMethodSignature(
- CharOperation.NO_CHAR_CHAR,
- CharOperation.NO_CHAR_CHAR,
- CharOperation.NO_CHAR,
- CharOperation.NO_CHAR));
- //proposal.setOriginalSignature(null);
- //proposal.setUniqueKey(null);
- proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
- proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
- //proposal.setParameterPackageNames(null);
- //proposal.setParameterTypeNames(null);
- //proposal.setPackageName(null);
- //proposal.setTypeName(null);
- proposal.setCompletion(completion);
- proposal.setFlags(Flags.AccPublic);
- proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenEnd - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
+ if (!exactMatch) {
+ if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
+ char[] packageName = currentType.isLocalType() ? null : currentType.qualifiedPackageName();
+ char[] typeName = currentType.qualifiedSourceName();
+
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(currentType));
+ proposal.setDeclarationKey(currentType.computeUniqueKey());
+ proposal.setSignature(
+ createMethodSignature(
+ CharOperation.NO_CHAR_CHAR,
+ CharOperation.NO_CHAR_CHAR,
+ CharOperation.NO_CHAR,
+ CharOperation.NO_CHAR));
+ //proposal.setOriginalSignature(null);
+ //proposal.setUniqueKey(null);
+ proposal.setDeclarationPackageName(packageName);
+ proposal.setDeclarationTypeName(typeName);
+ //proposal.setParameterPackageNames(null);
+ //proposal.setParameterTypeNames(null);
+ //proposal.setPackageName(null);
+ //proposal.setTypeName(null);
+ proposal.setName(currentType.sourceName());
+
+ InternalCompletionProposal typeProposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+ typeProposal.nameLookup = this.nameEnvironment.nameLookup;
+ typeProposal.completionEngine = this;
+ typeProposal.setDeclarationSignature(packageName);
+ typeProposal.setSignature(getRequiredTypeSignature(currentType));
+ typeProposal.setPackageName(packageName);
+ typeProposal.setTypeName(typeName);
+ typeProposal.setCompletion(typeCompletion);
+ typeProposal.setFlags(currentType.modifiers);
+ typeProposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ typeProposal.setTokenRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ typeProposal.setRelevance(relevance);
+ proposal.setRequiredProposals( new CompletionProposal[]{typeProposal});
+
+ proposal.setCompletion(completion);
+ proposal.setFlags(Flags.AccPublic);
+ proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ } else {
+ if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(currentType));
+ proposal.setDeclarationKey(currentType.computeUniqueKey());
+ proposal.setSignature(
+ createMethodSignature(
+ CharOperation.NO_CHAR_CHAR,
+ CharOperation.NO_CHAR_CHAR,
+ CharOperation.NO_CHAR,
+ CharOperation.NO_CHAR));
+ //proposal.setOriginalSignature(null);
+ //proposal.setUniqueKey(null);
+ proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
+ proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
+ //proposal.setParameterPackageNames(null);
+ //proposal.setParameterTypeNames(null);
+ //proposal.setPackageName(null);
+ //proposal.setTypeName(null);
+ proposal.setCompletion(completion);
+ proposal.setFlags(Flags.AccPublic);
+ proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenEnd - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
}
}
} else {
@@ -3990,7 +4578,10 @@
argTypes,
scope,
invocationSite,
- true);
+ true,
+ exactMatch,
+ isQualified,
+ relevance);
}
}
private void findClassField(
@@ -4075,6 +4666,24 @@
Scope scope,
InvocationSite invocationSite,
boolean forAnonymousType) {
+
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+
+ findConstructors(currentType, argTypes, scope, invocationSite, forAnonymousType, true, false, relevance);
+ }
+
+ private void findConstructors(
+ ReferenceBinding currentType,
+ TypeBinding[] argTypes,
+ Scope scope,
+ InvocationSite invocationSite,
+ boolean forAnonymousType,
+ boolean exactMatch,
+ boolean isQualified,
+ int relevance) {
// No visibility checks can be performed without the scope & invocationSite
MethodBinding[] methods = currentType.availableMethods();
@@ -4117,46 +4726,102 @@
char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);
char[] completion = CharOperation.NO_CHAR;
+
if(forAnonymousType){
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
-
+ char[] typeCompletion = null;
+ if (!exactMatch) {
+ typeCompletion =
+ isQualified ?
+ CharOperation.concat(currentType.qualifiedPackageName(), currentType.qualifiedSourceName(), '.') :
+ currentType.sourceName();
+ if (this.source != null
+ && this.source.length > this.endPosition
+ && this.source[this.endPosition] == '(') {
+ completion = CharOperation.NO_CHAR;
+ } else {
+ completion = new char[] { '(', ')' };
+ }
+ }
+
this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(currentType));
- proposal.setDeclarationKey(currentType.computeUniqueKey());
- proposal.setSignature(getSignature(constructor));
- MethodBinding original = constructor.original();
- if(original != constructor) {
- proposal.setOriginalSignature(getSignature(original));
+ if (!exactMatch) {
+ if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
+ char[] packageName = currentType.isLocalType() ? null : currentType.qualifiedPackageName();
+ char[] typeName = currentType.qualifiedSourceName();
+
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(currentType));
+ proposal.setDeclarationKey(currentType.computeUniqueKey());
+ proposal.setSignature(getSignature(constructor));
+ MethodBinding original = constructor.original();
+ if(original != constructor) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
+ proposal.setKey(constructor.computeUniqueKey());
+ proposal.setDeclarationPackageName(packageName);
+ proposal.setDeclarationTypeName(typeName);
+ proposal.setParameterPackageNames(parameterPackageNames);
+ proposal.setParameterTypeNames(parameterTypeNames);
+ //proposal.setPackageName(null);
+ //proposal.setTypeName(null);
+ proposal.setName(currentType.sourceName());
+
+ InternalCompletionProposal typeProposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+ typeProposal.nameLookup = this.nameEnvironment.nameLookup;
+ typeProposal.completionEngine = this;
+ typeProposal.setDeclarationSignature(packageName);
+ typeProposal.setSignature(getRequiredTypeSignature(currentType));
+ typeProposal.setPackageName(packageName);
+ typeProposal.setTypeName(typeName);
+ typeProposal.setCompletion(typeCompletion);
+ typeProposal.setFlags(currentType.modifiers);
+ typeProposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ typeProposal.setTokenRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ typeProposal.setRelevance(relevance);
+ proposal.setRequiredProposals( new CompletionProposal[]{typeProposal});
+
+ proposal.setCompletion(completion);
+ proposal.setFlags(constructor.modifiers);
+ proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ if(parameterNames != null) proposal.setParameterNames(parameterNames);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
}
- proposal.setKey(constructor.computeUniqueKey());
- proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
- proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
- proposal.setParameterPackageNames(parameterPackageNames);
- proposal.setParameterTypeNames(parameterTypeNames);
- //proposal.setPackageName(null);
- //proposal.setTypeName(null);
- proposal.setCompletion(completion);
- proposal.setFlags(constructor.modifiers);
- proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenEnd - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- if(parameterNames != null) proposal.setParameterNames(parameterNames);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
+ } else {
+ if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(currentType));
+ proposal.setDeclarationKey(currentType.computeUniqueKey());
+ proposal.setSignature(getSignature(constructor));
+ MethodBinding original = constructor.original();
+ if(original != constructor) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
+ proposal.setKey(constructor.computeUniqueKey());
+ proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
+ proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
+ proposal.setParameterPackageNames(parameterPackageNames);
+ proposal.setParameterTypeNames(parameterTypeNames);
+ //proposal.setPackageName(null);
+ //proposal.setTypeName(null);
+ proposal.setCompletion(completion);
+ proposal.setFlags(constructor.modifiers);
+ proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenEnd - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ if(parameterNames != null) proposal.setParameterNames(parameterNames);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
}
}
} else {
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
-
+ char[] typeCompletion = null;
// Special case for completion in javadoc
if (this.assistNodeInJavadoc > 0) {
Expression receiver = null;
@@ -4208,71 +4873,254 @@
javadocCompletion.append(')');
completion = javadocCompletion.toString().toCharArray();
}
+ } else {
+ if (!exactMatch) {
+ typeCompletion =
+ isQualified ?
+ CharOperation.concat(currentType.qualifiedPackageName(), currentType.qualifiedSourceName(), '.') :
+ currentType.sourceName();
+
+ if (this.source != null
+ && this.source.length > this.endPosition
+ && this.source[this.endPosition] == '(') {
+ completion = CharOperation.NO_CHAR;
+ } else {
+ completion = new char[] { '(', ')' };
+ }
+ }
}
// Create standard proposal
this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(currentType));
- proposal.setSignature(getSignature(constructor));
- MethodBinding original = constructor.original();
- if(original != constructor) {
- proposal.setOriginalSignature(getSignature(original));
+ if (!exactMatch) {
+ if(!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
+ char[] packageName = currentType.isLocalType() ? null : currentType.qualifiedPackageName();
+ char[] typeName = currentType.qualifiedSourceName();
+
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(currentType));
+ proposal.setSignature(getSignature(constructor));
+ MethodBinding original = constructor.original();
+ if(original != constructor) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
+ proposal.setDeclarationPackageName(packageName);
+ proposal.setDeclarationTypeName(typeName);
+ proposal.setParameterPackageNames(parameterPackageNames);
+ proposal.setParameterTypeNames(parameterTypeNames);
+ //proposal.setPackageName(null);
+ //proposal.setTypeName(null);
+ proposal.setName(currentType.sourceName());
+
+ InternalCompletionProposal typeProposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+ typeProposal.nameLookup = this.nameEnvironment.nameLookup;
+ typeProposal.completionEngine = this;
+ typeProposal.setDeclarationSignature(packageName);
+ typeProposal.setSignature(getRequiredTypeSignature(currentType));
+ typeProposal.setPackageName(packageName);
+ typeProposal.setTypeName(typeName);
+ typeProposal.setCompletion(typeCompletion);
+ typeProposal.setFlags(currentType.modifiers);
+ typeProposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ typeProposal.setTokenRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ typeProposal.setRelevance(relevance);
+ proposal.setRequiredProposals( new CompletionProposal[]{typeProposal});
+
+ proposal.setIsContructor(true);
+ proposal.setCompletion(completion);
+ proposal.setFlags(constructor.modifiers);
+ proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ if(parameterNames != null) proposal.setParameterNames(parameterNames);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
}
- proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
- proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
- proposal.setParameterPackageNames(parameterPackageNames);
- proposal.setParameterTypeNames(parameterTypeNames);
- //proposal.setPackageName(null);
- //proposal.setTypeName(null);
- proposal.setName(currentType.sourceName());
- proposal.setIsContructor(true);
- proposal.setCompletion(completion);
- proposal.setFlags(constructor.modifiers);
- int start = (this.assistNodeInJavadoc > 0) ? this.startPosition : this.endPosition;
- proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- if(parameterNames != null) proposal.setParameterNames(parameterNames);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
+ } else {
+ if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(currentType));
+ proposal.setSignature(getSignature(constructor));
+ MethodBinding original = constructor.original();
+ if(original != constructor) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
+ proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
+ proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
+ proposal.setParameterPackageNames(parameterPackageNames);
+ proposal.setParameterTypeNames(parameterTypeNames);
+ //proposal.setPackageName(null);
+ //proposal.setTypeName(null);
+ proposal.setName(currentType.sourceName());
+ proposal.setIsContructor(true);
+ proposal.setCompletion(completion);
+ proposal.setFlags(constructor.modifiers);
+ int start = (this.assistNodeInJavadoc > 0) ? this.startPosition : this.endPosition;
+ proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ if(parameterNames != null) proposal.setParameterNames(parameterNames);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
}
- }
- if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
- char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
- InternalCompletionProposal proposal = createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(currentType));
- proposal.setSignature(getSignature(constructor));
- MethodBinding original = constructor.original();
- if(original != constructor) {
- proposal.setOriginalSignature(getSignature(original));
+ if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
+ char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(currentType));
+ proposal.setSignature(getSignature(constructor));
+ MethodBinding original = constructor.original();
+ if(original != constructor) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
+ proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
+ proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
+ proposal.setParameterPackageNames(parameterPackageNames);
+ proposal.setParameterTypeNames(parameterTypeNames);
+ //proposal.setPackageName(null);
+ //proposal.setTypeName(null);
+ proposal.setName(currentType.sourceName());
+ proposal.setIsContructor(true);
+ proposal.setCompletion(javadocCompletion);
+ proposal.setFlags(constructor.modifiers);
+ int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
+ proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance+R_INLINE_TAG);
+ if(parameterNames != null) proposal.setParameterNames(parameterNames);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
}
- proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
- proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
- proposal.setParameterPackageNames(parameterPackageNames);
- proposal.setParameterTypeNames(parameterTypeNames);
- //proposal.setPackageName(null);
- //proposal.setTypeName(null);
- proposal.setName(currentType.sourceName());
- proposal.setIsContructor(true);
- proposal.setCompletion(javadocCompletion);
- proposal.setFlags(constructor.modifiers);
- int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
- proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance+R_INLINE_TAG);
- if(parameterNames != null) proposal.setParameterNames(parameterNames);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private char[] getResolvedSignature(char[][] parameterTypes, char[] fullyQualifiedTypeName, int parameterCount, Scope scope) {
+ char[][] cn = CharOperation.splitOn('.', fullyQualifiedTypeName);
+
+ TypeReference ref;
+ if (cn.length == 1) {
+ ref = new SingleTypeReference(cn[0], 0);
+ } else {
+ ref = new QualifiedTypeReference(cn,new long[cn.length]);
+ }
+
+ TypeBinding guessedType = null;
+ INameEnvironment oldNameEnvironment = this.lookupEnvironment.nameEnvironment;
+ this.lookupEnvironment.nameEnvironment = getNoCacheNameEnvironment();
+ try {
+ switch (scope.kind) {
+ case Scope.METHOD_SCOPE :
+ case Scope.BLOCK_SCOPE :
+ guessedType = ref.resolveType((BlockScope)scope);
+ break;
+ case Scope.CLASS_SCOPE :
+ guessedType = ref.resolveType((ClassScope)scope);
+ break;
+ }
+ } finally {
+ this.lookupEnvironment.nameEnvironment = oldNameEnvironment;
+ }
+
+ if (guessedType != null && guessedType.isValidBinding()) {
+ if (guessedType instanceof ReferenceBinding) {
+ ReferenceBinding refBinding = (ReferenceBinding) guessedType;
+
+ MethodBinding bestConstructor = null;
+ int[] bestMatchingLengths = null;
+
+ MethodBinding[] methods = refBinding.methods();
+ next : for (int i = 0; i < methods.length; i++) {
+ MethodBinding method = methods[i];
+
+ if (!method.isConstructor()) break next;
+
+ TypeBinding[] parameters = method.parameters;
+ //TODO take careful of member types
+ int parametersLength = parameters == null ? 0 : parameters.length;
+ if (parameterCount != parametersLength) continue next;
+
+ int[] matchingLengths = new int[parameterCount];
+ for (int j = 0; j < parametersLength; j++) {
+ TypeBinding parameter = parameters[j];
+
+ char[] parameterTypeName;
+ if (parameter instanceof ReferenceBinding) {
+ parameterTypeName = CharOperation.concatWith(((ReferenceBinding)parameter).compoundName, '.');
+ } else {
+ parameterTypeName = parameter.sourceName();
+ }
+
+ if (!CharOperation.endsWith(parameterTypeName, parameterTypes[j])) {
+ break next;
+ }
+
+ int matchingLength = parameterTypes[j].length;
+
+ if (bestMatchingLengths != null) {
+ if (bestMatchingLengths[j] > matchingLength) {
+ continue next;
}
}
+
+ matchingLengths[j] = matchingLength;
}
+
+
+ bestConstructor = method;
+ bestMatchingLengths = matchingLengths;
}
+
+ if (bestConstructor == null) return null;
+ return getSignature(bestConstructor);
}
}
+
+ return null;
+ }
+
+ private void findConstructorsOrAnonymousTypes(
+ ReferenceBinding currentType,
+ Scope scope,
+ InvocationSite invocationSite,
+ boolean isQualified,
+ int relevance) {
+
+ if (!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)
+ && currentType.isClass()
+ && !currentType.isAbstract()) {
+ findConstructors(
+ currentType,
+ null,
+ scope,
+ invocationSite,
+ false,
+ false,
+ isQualified,
+ relevance);
+ }
+
+ // This code is disabled because there is too much proposals when constructors and anonymous are proposed
+ if (!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)
+ && !currentType.isFinal()
+ && (currentType.isInterface() || (currentType.isClass() && currentType.isAbstract()))){
+ findAnonymousType(
+ currentType,
+ null,
+ scope,
+ invocationSite,
+ false,
+ isQualified,
+ relevance);
+ }
}
private char[][] findEnclosingTypeNames(Scope scope){
char[][] excludedNames = new char[10][];
@@ -8230,17 +9078,30 @@
relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
}
+ boolean allowingLongComputationProposals = isAllowingLongComputationProposals();
+
this.noProposal = false;
- createTypeProposal(
- memberType,
- memberType.qualifiedSourceName(),
- IAccessRule.K_ACCESSIBLE,
- completionName,
- relevance,
- missingElements,
- missingElementsStarts,
- missingElementsEnds,
- missingElementsHaveProblems);
+ if (!this.assistNodeIsConstructor || !allowingLongComputationProposals || hasStaticMemberTypes(memberType, invocationType, this.unitScope)) {
+ createTypeProposal(
+ memberType,
+ memberType.qualifiedSourceName(),
+ IAccessRule.K_ACCESSIBLE,
+ completionName,
+ relevance,
+ missingElements,
+ missingElementsStarts,
+ missingElementsEnds,
+ missingElementsHaveProblems);
+ }
+
+ if (this.assistNodeIsConstructor && allowingLongComputationProposals) {
+ findConstructorsOrAnonymousTypes(
+ memberType,
+ scope,
+ FakeInvocationSite,
+ isQualified,
+ relevance);
+ }
}
}
private void findMemberTypesFromMissingType(
@@ -8659,18 +9520,30 @@
relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for nested type
relevance += computeRelevanceForAnnotationTarget(localType);
- this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
- createTypeProposal(
+ boolean allowingLongComputationProposals = isAllowingLongComputationProposals();
+ if (!this.assistNodeIsConstructor || !allowingLongComputationProposals) {
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ createTypeProposal(
+ localType,
+ localType.sourceName,
+ IAccessRule.K_ACCESSIBLE,
+ localType.sourceName,
+ relevance,
+ null,
+ null,
+ null,
+ false);
+ }
+ }
+
+ if (this.assistNodeIsConstructor && allowingLongComputationProposals) {
+ findConstructorsOrAnonymousTypes(
localType,
- localType.sourceName,
- IAccessRule.K_ACCESSIBLE,
- localType.sourceName,
- relevance,
- null,
- null,
- null,
- false);
+ blockScope,
+ FakeInvocationSite,
+ false,
+ relevance);
}
}
}
@@ -8918,14 +9791,23 @@
if (token == null)
return;
-
+
+ boolean allowingLongComputationProposals = isAllowingLongComputationProposals();
+
boolean proposeType =
!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
boolean proposeAllMemberTypes = !this.assistNodeIsConstructor;
+
+ boolean proposeConstructor =
+ allowingLongComputationProposals &&
+ this.assistNodeIsConstructor &&
+ (!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF) ||
+ !isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF));
+
- if (proposeType && scope.enclosingSourceType() != null) {
+ if ((proposeType || proposeConstructor) && scope.enclosingSourceType() != null) {
checkCancel();
@@ -8944,7 +9826,7 @@
boolean isEmptyPrefix = token.length == 0;
- if (proposeType && this.unitScope != null) {
+ if ((proposeType || proposeConstructor) && this.unitScope != null) {
ReferenceBinding outerInvocationType = scope.enclosingSourceType();
if(outerInvocationType != null) {
@@ -8985,7 +9867,7 @@
if (typeLength > sourceType.sourceName.length) continue next;
if (!CharOperation.prefixEquals(token, sourceType.sourceName, false)
- && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName))) continue;
+ && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName))) continue next;
if (this.assistNodeIsAnnotation && !hasPossibleAnnotationTarget(sourceType, scope)) {
continue next;
@@ -8996,8 +9878,8 @@
if (sourceType == otherType) continue next;
}
-
- this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this);
+
+ typesFound.add(sourceType);
if(this.assistNodeIsClass) {
if(!sourceType.isClass()) continue next;
@@ -9028,8 +9910,10 @@
relevance += computeRelevanceForClass();
relevance += computeRelevanceForException(sourceType.sourceName);
}
+
+
this.noProposal = false;
- if(proposeType) {
+ if(proposeType && (!this.assistNodeIsConstructor || !allowingLongComputationProposals || hasStaticMemberTypes(sourceType, null, this.unitScope))) {
char[] typeName = sourceType.sourceName();
createTypeProposal(
sourceType,
@@ -9042,141 +9926,76 @@
null,
false);
}
+
+ if (proposeConstructor) {
+ findConstructorsOrAnonymousTypes(
+ sourceType,
+ scope,
+ FakeInvocationSite,
+ false,
+ relevance);
+ }
}
}
- if(proposeType) {
+ if (proposeConstructor && !isEmptyPrefix) {
+
+ checkCancel();
+
+ findTypesFromImports(token, scope, proposeType, typesFound);
+ } else if(proposeType) {
checkCancel();
findTypesFromStaticImports(token, scope, proposeAllMemberTypes, typesFound);
}
+
+ if (proposeConstructor) {
+
+ checkCancel();
+
+ findTypesFromExpectedTypes(token, scope, typesFound, proposeType, proposeConstructor);
+ }
if (isEmptyPrefix && !this.assistNodeIsAnnotation) {
- if(proposeType && this.expectedTypesPtr > -1) {
- next : for (int i = 0; i <= this.expectedTypesPtr; i++) {
-
- checkCancel();
-
- if(this.expectedTypes[i] instanceof ReferenceBinding) {
- ReferenceBinding refBinding = (ReferenceBinding)this.expectedTypes[i];
-
- if(refBinding.isTypeVariable() && this.assistNodeIsConstructor) {
- // don't propose type variable if the completion is a constructor ('new |')
- continue next;
- }
- if (this.options.checkDeprecation &&
- refBinding.isViewedAsDeprecated() &&
- !scope.isDefinedInSameUnit(refBinding))
- continue next;
-
- int accessibility = IAccessRule.K_ACCESSIBLE;
- if(refBinding.hasRestrictedAccess()) {
- AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding);
- if(accessRestriction != null) {
- switch (accessRestriction.getProblemId()) {
- case IProblem.ForbiddenReference:
- if (this.options.checkForbiddenReference) {
- continue next;
- }
- accessibility = IAccessRule.K_NON_ACCESSIBLE;
- break;
- case IProblem.DiscouragedReference:
- if (this.options.checkDiscouragedReference) {
- continue next;
- }
- accessibility = IAccessRule.K_DISCOURAGED;
- break;
- }
- }
- }
-
- for (int j = 0; j < typesFound.size(); j++) {
- ReferenceBinding typeFound = (ReferenceBinding)typesFound.elementAt(j);
- if (typeFound == refBinding) {
- continue next;
- }
- }
-
- boolean inSameUnit = this.unitScope.isDefinedInSameUnit(refBinding);
-
- // top level types of the current unit are already proposed.
- if(!inSameUnit || (inSameUnit && refBinding.isMemberType())) {
- char[] packageName = refBinding.qualifiedPackageName();
- char[] typeName = refBinding.sourceName();
- char[] completionName = typeName;
-
- boolean isQualified = false;
- if (!this.insideQualifiedReference && !refBinding.isMemberType()) {
- if (mustQualifyType(packageName, typeName, null, refBinding.modifiers)) {
- if (packageName == null || packageName.length == 0)
- if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
- continue next; // ignore types from the default package from outside it
- completionName = CharOperation.concat(packageName, typeName, '.');
- isQualified = true;
- }
- }
-
- if(this.assistNodeIsClass) {
- if(!refBinding.isClass()) continue next;
- } else if(this.assistNodeIsInterface) {
- if(!refBinding.isInterface() && !refBinding.isAnnotationType()) continue next;
- } else if (this.assistNodeIsAnnotation) {
- if(!refBinding.isAnnotationType()) continue next;
- }
-
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(token, typeName);
- relevance += computeRelevanceForExpectingType(refBinding);
- relevance += computeRelevanceForQualification(isQualified);
- relevance += computeRelevanceForRestrictions(accessibility);
-
- if(refBinding.isClass()) {
- relevance += computeRelevanceForClass();
- relevance += computeRelevanceForException(typeName);
- } else if(refBinding.isEnum()) {
- relevance += computeRelevanceForEnum();
- } else if(refBinding.isInterface()) {
- relevance += computeRelevanceForInterface();
- }
-
- this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(packageName);
- proposal.setSignature(getSignature(refBinding));
- proposal.setPackageName(packageName);
- proposal.setTypeName(typeName);
- proposal.setCompletion(completionName);
- proposal.setFlags(refBinding.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- proposal.setAccessibility(accessibility);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
+ if (!proposeConstructor) {
+ findTypesFromExpectedTypes(token, scope, typesFound, proposeType, proposeConstructor);
+ }
+ } else {
+ if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+ if (this.assistNodeInJavadoc == 0 || (this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0) {
+ if (proposeBaseTypes) {
+ if (proposeVoidType) {
+ findKeywords(token, BASE_TYPE_NAMES, false, false);
+ } else {
+ findKeywords(token, BASE_TYPE_NAMES_WITHOUT_VOID, false, false);
}
}
}
}
- } else {
- if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
- if (this.assistNodeInJavadoc == 0 || (this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0) {
- if (proposeBaseTypes) {
- if (proposeVoidType) {
- findKeywords(token, BASE_TYPE_NAMES, false, false);
- } else {
- findKeywords(token, BASE_TYPE_NAMES_WITHOUT_VOID, false, false);
- }
- }
+
+ if (proposeConstructor) {
+ int l = typesFound.size();
+ for (int i = 0; i < l; i++) {
+ ReferenceBinding typeFound = (ReferenceBinding) typesFound.elementAt(i);
+ char[] fullyQualifiedTypeName =
+ CharOperation.concat(
+ typeFound.qualifiedPackageName(),
+ typeFound.qualifiedSourceName(),
+ '.');
+ this.knownTypes.put(fullyQualifiedTypeName, KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS);
}
- }
- if(proposeType) {
+
+ checkCancel();
+
+ this.foundConstructorsCount = 0;
+ this.nameEnvironment.findConstructorDeclarations(
+ token,
+ this.options.camelCaseMatch,
+ this,
+ this.monitor);
+ acceptConstructors(scope);
+ } else if (proposeType) {
int l = typesFound.size();
for (int i = 0; i < l; i++) {
ReferenceBinding typeFound = (ReferenceBinding) typesFound.elementAt(i);
@@ -9185,7 +10004,7 @@
typeFound.qualifiedPackageName(),
typeFound.qualifiedSourceName(),
'.');
- this.knownTypes.put(fullyQualifiedTypeName, this);
+ this.knownTypes.put(fullyQualifiedTypeName, KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS);
}
int searchFor = IJavaSearchConstants.TYPE;
if(this.assistNodeIsClass) {
@@ -9223,10 +10042,18 @@
char[] token,
PackageBinding packageBinding,
Scope scope) {
+
+ boolean allowingLongComputationProposals = isAllowingLongComputationProposals();
boolean proposeType =
!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
+
+ boolean proposeConstructor =
+ allowingLongComputationProposals &&
+ this.assistNodeIsConstructor &&
+ (!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF) ||
+ !isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF));
char[] qualifiedName =
CharOperation.concatWith(packageBinding.compoundName, token, '.');
@@ -9244,7 +10071,7 @@
this.qualifiedCompletionToken = qualifiedName;
- if (proposeType && this.unitScope != null) {
+ if ((proposeType || proposeConstructor) && this.unitScope != null) {
int typeLength = qualifiedName.length;
SourceTypeBinding[] types = this.unitScope.topLevelTypes;
@@ -9290,7 +10117,7 @@
}
}
- this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this);
+ this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS);
int relevance = computeBaseRelevance();
relevance += computeRelevanceForResolution();
@@ -9308,8 +10135,9 @@
relevance += computeRelevanceForClass();
relevance += computeRelevanceForException(sourceType.sourceName);
}
+
this.noProposal = false;
- if(proposeType) {
+ if(proposeType && (!this.assistNodeIsConstructor || !allowingLongComputationProposals || hasStaticMemberTypes(sourceType, null, this.unitScope))) {
char[] typeName = sourceType.sourceName();
createTypeProposal(
sourceType,
@@ -9322,10 +10150,31 @@
null,
false);
}
+
+ if (proposeConstructor) {
+ findConstructorsOrAnonymousTypes(
+ sourceType,
+ scope,
+ FakeInvocationSite,
+ false,
+ relevance);
+ }
}
}
- if(proposeType) {
+ if (proposeConstructor) {
+
+
+ checkCancel();
+
+ this.foundConstructorsCount = 0;
+ this.nameEnvironment.findConstructorDeclarations(
+ qualifiedName,
+ this.options.camelCaseMatch,
+ this,
+ this.monitor);
+ acceptConstructors(scope);
+ } if(proposeType) {
int searchFor = IJavaSearchConstants.TYPE;
if(this.assistNodeIsClass) {
searchFor = IJavaSearchConstants.CLASS;
@@ -9349,11 +10198,275 @@
this.monitor);
acceptTypes(scope);
}
+
if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
this.nameEnvironment.findPackages(qualifiedName, this);
}
}
+
+ private void findTypesFromExpectedTypes(char[] token, Scope scope, ObjectVector typesFound, boolean proposeType, boolean proposeConstructor) {
+ if(this.expectedTypesPtr > -1) {
+ boolean allowingLongComputationProposals = isAllowingLongComputationProposals();
+
+ int typeLength = token == null ? 0 : token.length;
+
+ next : for (int i = 0; i <= this.expectedTypesPtr; i++) {
+
+ checkCancel();
+
+ if(this.expectedTypes[i] instanceof ReferenceBinding) {
+ ReferenceBinding refBinding = (ReferenceBinding)this.expectedTypes[i];
+
+ if (typeLength > 0) {
+ if (typeLength > refBinding.sourceName.length) continue next;
+
+ if (!CharOperation.prefixEquals(token, refBinding.sourceName, false)
+ && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, refBinding.sourceName))) continue next;
+ }
+
+
+ if(refBinding.isTypeVariable() && this.assistNodeIsConstructor) {
+ // don't propose type variable if the completion is a constructor ('new |')
+ continue next;
+ }
+ if (this.options.checkDeprecation &&
+ refBinding.isViewedAsDeprecated() &&
+ !scope.isDefinedInSameUnit(refBinding))
+ continue next;
+
+ int accessibility = IAccessRule.K_ACCESSIBLE;
+ if(refBinding.hasRestrictedAccess()) {
+ AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding);
+ if(accessRestriction != null) {
+ switch (accessRestriction.getProblemId()) {
+ case IProblem.ForbiddenReference:
+ if (this.options.checkForbiddenReference) {
+ continue next;
+ }
+ accessibility = IAccessRule.K_NON_ACCESSIBLE;
+ break;
+ case IProblem.DiscouragedReference:
+ if (this.options.checkDiscouragedReference) {
+ continue next;
+ }
+ accessibility = IAccessRule.K_DISCOURAGED;
+ break;
+ }
+ }
+ }
+
+ for (int j = 0; j < typesFound.size(); j++) {
+ ReferenceBinding typeFound = (ReferenceBinding)typesFound.elementAt(j);
+ if (typeFound == refBinding) {
+ continue next;
+ }
+ }
+
+ typesFound.add(refBinding);
+ boolean inSameUnit = this.unitScope.isDefinedInSameUnit(refBinding);
+
+ // top level types of the current unit are already proposed.
+ if(!inSameUnit || (inSameUnit && refBinding.isMemberType())) {
+ char[] packageName = refBinding.qualifiedPackageName();
+ char[] typeName = refBinding.sourceName();
+ char[] completionName = typeName;
+
+ boolean isQualified = false;
+ if (!this.insideQualifiedReference && !refBinding.isMemberType()) {
+ if (mustQualifyType(packageName, typeName, null, refBinding.modifiers)) {
+ if (packageName == null || packageName.length == 0)
+ if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
+ continue next; // ignore types from the default package from outside it
+ completionName = CharOperation.concat(packageName, typeName, '.');
+ isQualified = true;
+ }
+ }
+
+ if(this.assistNodeIsClass) {
+ if(!refBinding.isClass()) continue next;
+ } else if(this.assistNodeIsInterface) {
+ if(!refBinding.isInterface() && !refBinding.isAnnotationType()) continue next;
+ } else if (this.assistNodeIsAnnotation) {
+ if(!refBinding.isAnnotationType()) continue next;
+ }
+
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(token, typeName);
+ relevance += computeRelevanceForExpectingType(refBinding);
+ relevance += computeRelevanceForQualification(isQualified);
+ relevance += computeRelevanceForRestrictions(accessibility);
+
+ if(refBinding.isClass()) {
+ relevance += computeRelevanceForClass();
+ relevance += computeRelevanceForException(typeName);
+ } else if(refBinding.isEnum()) {
+ relevance += computeRelevanceForEnum();
+ } else if(refBinding.isInterface()) {
+ relevance += computeRelevanceForInterface();
+ }
+
+ if (proposeType && (!this.assistNodeIsConstructor || !allowingLongComputationProposals || hasStaticMemberTypes(refBinding, scope.enclosingSourceType() ,this.unitScope))) {
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(packageName);
+ proposal.setSignature(getSignature(refBinding));
+ proposal.setPackageName(packageName);
+ proposal.setTypeName(typeName);
+ proposal.setCompletion(completionName);
+ proposal.setFlags(refBinding.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ proposal.setAccessibility(accessibility);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ }
+
+ if (proposeConstructor) {
+ findConstructorsOrAnonymousTypes(
+ refBinding,
+ scope,
+ FakeInvocationSite,
+ isQualified,
+ relevance);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void findTypesFromImports(char[] token, Scope scope, boolean proposeType, ObjectVector typesFound) {
+ ImportBinding[] importBindings = scope.compilationUnitScope().imports;
+ next : for (int i = 0; i < importBindings.length; i++) {
+ ImportBinding importBinding = importBindings[i];
+ if(importBinding.isValidBinding()) {
+ Binding binding = importBinding.resolvedImport;
+ if(binding != null && binding.isValidBinding()) {
+ if(importBinding.onDemand) {
+ if (importBinding.isStatic()) {
+ if((binding.kind() & Binding.TYPE) != 0) {
+ this.findMemberTypes(
+ token,
+ (ReferenceBinding) binding,
+ scope,
+ scope.enclosingSourceType(),
+ true,
+ false,
+ true,
+ true,
+ false,
+ null,
+ typesFound,
+ null,
+ null,
+ null,
+ false);
+ }
+ }
+ } else {
+ if ((binding.kind() & Binding.TYPE) != 0) {
+ ReferenceBinding typeBinding = (ReferenceBinding) binding;
+ int typeLength = token.length;
+
+ if (!typeBinding.isStatic()) continue next;
+
+ if (typeLength > typeBinding.sourceName.length) continue next;
+
+ if (!CharOperation.prefixEquals(token, typeBinding.sourceName, false)
+ && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeBinding.sourceName))) continue next;
+
+ int accessibility = IAccessRule.K_ACCESSIBLE;
+ if(typeBinding.hasRestrictedAccess()) {
+ AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(typeBinding);
+ if(accessRestriction != null) {
+ switch (accessRestriction.getProblemId()) {
+ case IProblem.ForbiddenReference:
+ if (this.options.checkForbiddenReference) {
+ continue next;
+ }
+ accessibility = IAccessRule.K_NON_ACCESSIBLE;
+ break;
+ case IProblem.DiscouragedReference:
+ if (this.options.checkDiscouragedReference) {
+ continue next;
+ }
+ accessibility = IAccessRule.K_DISCOURAGED;
+ break;
+ }
+ }
+ }
+
+ if (typesFound.contains(typeBinding)) continue next;
+
+ typesFound.add(typeBinding);
+
+ if(this.assistNodeIsClass) {
+ if(!typeBinding.isClass()) continue;
+ } else if(this.assistNodeIsInterface) {
+ if(!typeBinding.isInterface() && !typeBinding.isAnnotationType()) continue;
+ } else if (this.assistNodeIsAnnotation) {
+ if(!typeBinding.isAnnotationType()) continue;
+ }
+
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(token, typeBinding.sourceName);
+ relevance += computeRelevanceForExpectingType(typeBinding);
+ relevance += computeRelevanceForQualification(false);
+ relevance += computeRelevanceForRestrictions(accessibility);
+
+ if (typeBinding.isAnnotationType()) {
+ relevance += computeRelevanceForAnnotation();
+ relevance += computeRelevanceForAnnotationTarget(typeBinding);
+ } else if (typeBinding.isInterface()) {
+ relevance += computeRelevanceForInterface();
+ } else if(typeBinding.isClass()){
+ relevance += computeRelevanceForClass();
+ relevance += computeRelevanceForException(typeBinding.sourceName);
+ }
+
+ if (proposeType && hasStaticMemberTypes(typeBinding, scope.enclosingSourceType(), this.unitScope)) {
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(typeBinding.qualifiedPackageName());
+ proposal.setSignature(getSignature(typeBinding));
+ proposal.setPackageName(typeBinding.qualifiedPackageName());
+ proposal.setTypeName(typeBinding.qualifiedSourceName());
+ proposal.setCompletion(typeBinding.sourceName());
+ proposal.setFlags(typeBinding.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ }
+
+ findConstructorsOrAnonymousTypes(
+ typeBinding,
+ scope,
+ FakeInvocationSite,
+ false,
+ relevance);
+ }
+ }
+ }
+ }
+ }
+ }
+
private void findTypesFromStaticImports(char[] token, Scope scope, boolean proposeAllMemberTypes, ObjectVector typesFound) {
ImportBinding[] importBindings = scope.compilationUnitScope().imports;
for (int i = 0; i < importBindings.length; i++) {
@@ -10206,6 +11319,14 @@
return this.favoriteReferenceBindings = resolvedImports;
}
+
+ private INameEnvironment getNoCacheNameEnvironment() {
+ if (this.noCacheNameEnvironment == null) {
+ JavaModelManager.getJavaModelManager().cacheZipFiles();
+ this.noCacheNameEnvironment = new JavaSearchNameEnvironment(this.javaProject, this.owner == null ? null : JavaModelManager.getJavaModelManager().getWorkingCopies(this.owner, true/*add primary WCs*/));
+ }
+ return this.noCacheNameEnvironment;
+ }
public AssistParser getParser() {
@@ -10256,6 +11377,9 @@
inlineCompletion[inlineLength-1] = '}';
return inlineCompletion;
}
+ private boolean isAllowingLongComputationProposals() {
+ return this.monitor != null;
+ }
private boolean isForbidden(Binding binding) {
for (int i = 0; i <= this.forbbidenBindingsPtr; i++) {
if(this.forbbidenBindings[i] == binding) {
@@ -10469,6 +11593,12 @@
case CompletionProposal.TYPE_IMPORT :
buffer.append("TYPE_IMPORT"); //$NON-NLS-1$
break;
+ case CompletionProposal.CONSTRUCTOR_INVOCATION :
+ buffer.append("CONSTRUCTOR_INVOCATION"); //$NON-NLS-1$
+ break;
+ case CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION :
+ buffer.append("ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION"); //$NON-NLS-1$
+ break;
default :
buffer.append("PROPOSAL"); //$NON-NLS-1$
break;
@@ -10540,6 +11670,290 @@
buffer.append('\t');
}
}
+
+ private void proposeConstructor(AcceptedConstructor deferredProposal, Scope scope) {
+ if (deferredProposal.proposeConstructor) {
+ proposeConstructor(
+ deferredProposal.simpleTypeName,
+ deferredProposal.parameterCount,
+ deferredProposal.signature,
+ deferredProposal.parameterTypes,
+ deferredProposal.parameterNames,
+ deferredProposal.modifiers,
+ deferredProposal.packageName,
+ deferredProposal.typeModifiers,
+ deferredProposal.accessibility,
+ deferredProposal.simpleTypeName,
+ deferredProposal.fullyQualifiedName,
+ deferredProposal.mustBeQualified,
+ scope,
+ deferredProposal.extraFlags);
+ }
+ }
+
+ private void proposeConstructor(
+ char[] simpleTypeName,
+ int parameterCount,
+ char[] signature,
+ char[][] parameterTypes,
+ char[][] parameterNames,
+ int modifiers,
+ char[] packageName,
+ int typeModifiers,
+ int accessibility,
+ char[] typeName,
+ char[] fullyQualifiedName,
+ boolean isQualified,
+ Scope scope,
+ int extraFlags) {
+ char[] typeCompletion = fullyQualifiedName;
+ if(isQualified) {
+ if (packageName == null || packageName.length == 0)
+ if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
+ return; // ignore types from the default package from outside it
+ } else {
+ typeCompletion = simpleTypeName;
+ }
+
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForRestrictions(accessibility);
+ relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
+ relevance += computeRelevanceForExpectingType(packageName, simpleTypeName);
+ relevance += computeRelevanceForQualification(isQualified);
+
+ boolean isInterface = false;
+ int kind = typeModifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation);
+ switch (kind) {
+ case ClassFileConstants.AccAnnotation:
+ case ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface:
+ relevance += computeRelevanceForAnnotation();
+ relevance += computeRelevanceForInterface();
+ isInterface = true;
+ break;
+ case ClassFileConstants.AccEnum:
+ relevance += computeRelevanceForEnum();
+ break;
+ case ClassFileConstants.AccInterface:
+ relevance += computeRelevanceForInterface();
+ isInterface = true;
+ break;
+ default:
+ relevance += computeRelevanceForClass();
+ relevance += computeRelevanceForException(simpleTypeName);
+ break;
+ }
+
+ char[] completion;
+ if (this.source != null
+ && this.source.length > this.endPosition
+ && this.source[this.endPosition] == '(') {
+ completion = CharOperation.NO_CHAR;
+ } else {
+ completion = new char[] { '(', ')' };
+ }
+
+ InternalCompletionProposal typeProposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+ typeProposal.nameLookup = this.nameEnvironment.nameLookup;
+ typeProposal.completionEngine = this;
+ typeProposal.setDeclarationSignature(packageName);
+ typeProposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
+ typeProposal.setPackageName(packageName);
+ typeProposal.setTypeName(typeName);
+ typeProposal.setCompletion(typeCompletion);
+ typeProposal.setFlags(typeModifiers);
+ typeProposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ typeProposal.setTokenRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ typeProposal.setRelevance(relevance);
+
+ switch (parameterCount) {
+ case -1: // default constructor
+ int flags = Flags.AccPublic;
+ if (Flags.isDeprecated(typeModifiers)) {
+ flags |= Flags.AccDeprecated;
+ }
+
+ if (isInterface || (typeModifiers & ClassFileConstants.AccAbstract) != 0) {
+ this.noProposal = false;
+ if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName));
+ proposal.setDeclarationKey(createBindingKey(packageName, typeName));
+ proposal.setSignature(DEFAULT_CONSTRUCTOR_SIGNATURE);
+ proposal.setDeclarationPackageName(packageName);
+ proposal.setDeclarationTypeName(typeName);
+ proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR);
+ proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR);
+ proposal.setParameterNames(CharOperation.NO_CHAR_CHAR);
+ proposal.setName(simpleTypeName);
+ proposal.setRequiredProposals(new CompletionProposal[]{typeProposal});
+ proposal.setIsContructor(true);
+ proposal.setCompletion(completion);
+ proposal.setFlags(flags);
+ proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ } else {
+ this.noProposal = false;
+ if(!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName));
+ proposal.setSignature(DEFAULT_CONSTRUCTOR_SIGNATURE);
+ proposal.setDeclarationPackageName(packageName);
+ proposal.setDeclarationTypeName(typeName);
+ proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR);
+ proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR);
+ proposal.setParameterNames(CharOperation.NO_CHAR_CHAR);
+ proposal.setName(simpleTypeName);
+ proposal.setRequiredProposals(new CompletionProposal[]{typeProposal});
+ proposal.setIsContructor(true);
+ proposal.setCompletion(completion);
+ proposal.setFlags(flags);
+ proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ }
+ break;
+ case 0: // constructor with no parameter
+
+ if ((typeModifiers & ClassFileConstants.AccAbstract) != 0) {
+ this.noProposal = false;
+ if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName));
+ proposal.setDeclarationKey(createBindingKey(packageName, typeName));
+ proposal.setSignature(DEFAULT_CONSTRUCTOR_SIGNATURE);
+ proposal.setDeclarationPackageName(packageName);
+ proposal.setDeclarationTypeName(typeName);
+ proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR);
+ proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR);
+ proposal.setParameterNames(CharOperation.NO_CHAR_CHAR);
+ proposal.setName(simpleTypeName);
+ proposal.setRequiredProposals(new CompletionProposal[]{typeProposal});
+ proposal.setIsContructor(true);
+ proposal.setCompletion(completion);
+ proposal.setFlags(modifiers);
+ proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ } else {
+ this.noProposal = false;
+ if(!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName));
+ proposal.setSignature(DEFAULT_CONSTRUCTOR_SIGNATURE);
+ proposal.setDeclarationPackageName(packageName);
+ proposal.setDeclarationTypeName(typeName);
+ proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR);
+ proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR);
+ proposal.setParameterNames(CharOperation.NO_CHAR_CHAR);
+ proposal.setName(simpleTypeName);
+ proposal.setRequiredProposals(new CompletionProposal[]{typeProposal});
+ proposal.setIsContructor(true);
+ proposal.setCompletion(completion);
+ proposal.setFlags(modifiers);
+ proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ }
+ break;
+ default: // constructor with parameter
+ if (signature == null) {
+ // resolve type to found parameter types
+ signature = getResolvedSignature(parameterTypes, fullyQualifiedName, parameterCount, scope);
+ if (signature == null) return;
+ } else {
+ signature = CharOperation.replaceOnCopy(signature, '/', '.');
+ }
+
+ int parameterNamesLength = parameterNames == null ? 0 : parameterNames.length;
+ if (parameterCount != parameterNamesLength) {
+ parameterNames = null;
+ }
+
+ if ((typeModifiers & ClassFileConstants.AccAbstract) != 0) {
+ this.noProposal = false;
+ if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName));
+ proposal.setDeclarationKey(createBindingKey(packageName, typeName));
+ proposal.setSignature(signature);
+ proposal.setDeclarationPackageName(packageName);
+ proposal.setDeclarationTypeName(typeName);
+ proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR);
+ proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR);
+ if (parameterNames != null) {
+ proposal.setParameterNames(parameterNames);
+ } else {
+ proposal.setHasNoParameterNamesFromIndex(true);
+ }
+ proposal.setName(simpleTypeName);
+ proposal.setRequiredProposals(new CompletionProposal[]{typeProposal});
+ proposal.setIsContructor(true);
+ proposal.setCompletion(completion);
+ proposal.setFlags(modifiers);
+ proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ } else {
+ this.noProposal = false;
+ if(!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName));
+ proposal.setSignature(signature);
+ proposal.setDeclarationPackageName(packageName);
+ proposal.setDeclarationTypeName(typeName);
+ proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR);
+ proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR);
+ if (parameterNames != null) {
+ proposal.setParameterNames(parameterNames);
+ } else {
+ proposal.setHasNoParameterNamesFromIndex(true);
+ }
+ proposal.setName(simpleTypeName);
+ proposal.setRequiredProposals(new CompletionProposal[]{typeProposal});
+ proposal.setIsContructor(true);
+ proposal.setCompletion(completion);
+ proposal.setFlags(modifiers);
+ proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ }
+ break;
+ }
+ }
private void proposeNewMethod(char[] token, ReferenceBinding reference) {
if(!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
@@ -10662,6 +12076,11 @@
super.reset(false);
this.knownPkgs = new HashtableOfObject(10);
this.knownTypes = new HashtableOfObject(10);
+ if (this.noCacheNameEnvironment != null) {
+ this.noCacheNameEnvironment.cleanup();
+ this.noCacheNameEnvironment = null;
+ JavaModelManager.getJavaModelManager().flushZipFiles();
+ }
}
private void setSourceAndTokenRange(int start, int end) {
Index: codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionProposal.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionProposal.java,v
retrieving revision 1.12
diff -u -r1.12 InternalCompletionProposal.java
--- codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionProposal.java 18 Sep 2008 14:06:39 -0000 1.12
+++ codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionProposal.java 14 Jan 2009 12:57:41 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2006 IBM Corporation and others.
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -18,13 +18,19 @@
import org.eclipse.jdt.core.IAccessRule;
import org.eclipse.jdt.core.ICodeAssist;
import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.env.IBinaryMethod;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
import org.eclipse.jdt.internal.core.BinaryType;
+import org.eclipse.jdt.internal.core.JavaElement;
import org.eclipse.jdt.internal.core.NameLookup;
+import org.eclipse.jdt.internal.core.SourceMapper;
/**
* Internal completion proposal
@@ -32,16 +38,8 @@
*/
public class InternalCompletionProposal extends CompletionProposal {
private static Object NO_ATTACHED_SOURCE = new Object();
+ private static final int OPENED_BYNARY_TYPES_THRESHOLD = 100; // threshold of opened binary to avoid to harm java model cache
- static final char[] ARG = "arg".toCharArray(); //$NON-NLS-1$
- static final char[] ARG0 = "arg0".toCharArray(); //$NON-NLS-1$
- static final char[] ARG1 = "arg1".toCharArray(); //$NON-NLS-1$
- static final char[] ARG2 = "arg2".toCharArray(); //$NON-NLS-1$
- static final char[] ARG3 = "arg3".toCharArray(); //$NON-NLS-1$
- static final char[][] ARGS1 = new char[][]{ARG0};
- static final char[][] ARGS2 = new char[][]{ARG0, ARG1};
- static final char[][] ARGS3 = new char[][]{ARG0, ARG1, ARG2};
- static final char[][] ARGS4 = new char[][]{ARG0, ARG1, ARG2, ARG3};
protected CompletionEngine completionEngine;
protected NameLookup nameLookup;
@@ -55,6 +53,7 @@
protected char[] originalSignature;
+ private boolean hasNoParameterNamesFromIndex = false;
private boolean updateCompletion = false;
protected int accessibility = IAccessRule.K_ACCESSIBLE;
@@ -179,34 +178,104 @@
* Indicates whether parameter names have been computed.
*/
private boolean parameterNamesComputed = false;
+
+ protected char[][] findConstructorParameterNames(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, char[][] paramTypeNames){
+ if(paramTypeNames == null || declaringTypeName == null) return null;
- protected char[][] createDefaultParameterNames(int length) {
- char[][] parameters;
- switch (length) {
- case 0 :
- parameters = new char[length][];
- break;
- case 1 :
- parameters = ARGS1;
- break;
- case 2 :
- parameters = ARGS2;
- break;
- case 3 :
- parameters = ARGS3;
- break;
- case 4 :
- parameters = ARGS4;
- break;
- default :
- parameters = new char[length][];
- for (int i = 0; i < length; i++) {
- parameters[i] = CharOperation.concat(ARG, String.valueOf(i).toCharArray());
+ char[][] parameters = null;
+ int length = paramTypeNames.length;
+
+ char[] tName = CharOperation.concat(declaringTypePackageName,declaringTypeName,'.');
+ Object cachedType = this.completionEngine.typeCache.get(tName);
+
+ IType type = null;
+ if(cachedType != null) {
+ if(cachedType != NO_ATTACHED_SOURCE && cachedType instanceof BinaryType) {
+ type = (BinaryType)cachedType;
+ }
+ } else {
+ // TODO (david) shouldn't it be NameLookup.ACCEPT_ALL ?
+ NameLookup.Answer answer = this.nameLookup.findType(new String(tName),
+ false,
+ NameLookup.ACCEPT_CLASSES & NameLookup.ACCEPT_INTERFACES,
+ true/* consider secondary types */,
+ false/* do NOT wait for indexes */,
+ false/*don't check restrictions*/,
+ null);
+ type = answer == null ? null : answer.type;
+ if(type instanceof BinaryType){
+ this.completionEngine.typeCache.put(tName, type);
+ } else {
+ type = null;
+ }
+ }
+
+ if(type != null) {
+ String[] args = new String[length];
+ for(int i = 0; i< length ; i++){
+ args[i] = new String(paramTypeNames[i]);
+ }
+ IMethod method = type.getMethod(new String(selector),args);
+
+ if (this.hasNoParameterNamesFromIndex) {
+ IPackageFragmentRoot packageFragmentRoot = (IPackageFragmentRoot)type.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+ if (packageFragmentRoot.isArchive() ||
+ this.completionEngine.openedBinaryTypes < OPENED_BYNARY_TYPES_THRESHOLD) {
+ SourceMapper mapper = ((JavaElement)method).getSourceMapper();
+ if (mapper != null) {
+ try {
+ char[][] paramNames = mapper.getMethodParameterNames(method);
+
+ // map source and try to find parameter names
+ if(paramNames == null) {
+ this.completionEngine.openedBinaryTypes++;
+ IBinaryType info = (IBinaryType) ((BinaryType) type).getElementInfo();
+ char[] source = mapper.findSource(type, info);
+ if (source != null){
+ mapper.mapSource(type, source, info);
+ }
+ paramNames = mapper.getMethodParameterNames(method);
+ }
+
+ if(paramNames != null) {
+ parameters = paramNames;
+ }
+ } catch(JavaModelException e){
+ //parameters == null;
+ }
+ }
}
- break;
+ } else {
+ try{
+ IBinaryMethod info = (IBinaryMethod) ((JavaElement)method).getElementInfo();
+ char[][] argumentNames = info.getArgumentNames();
+ if (argumentNames != null && argumentNames.length == length) {
+ parameters = argumentNames;
+ }
+ } catch(JavaModelException e){
+ //parameters == null;
+ }
+
+ try{
+ parameters = new char[length][];
+ String[] params = method.getParameterNames();
+ for(int i = 0; i< length ; i++){
+ parameters[i] = params[i].toCharArray();
+ }
+ } catch(JavaModelException e){
+ parameters = null;
+ }
+ }
+ }
+
+ // default parameters name
+ if(parameters == null) {
+ parameters = CompletionEngine.createDefaultParameterNames(length);
}
+
return parameters;
}
+
protected char[][] findMethodParameterNames(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, char[][] paramTypeNames){
if(paramTypeNames == null || declaringTypeName == null) return null;
@@ -257,7 +326,7 @@
// default parameters name
if(parameters == null) {
- parameters = createDefaultParameterNames(length);
+ parameters = CompletionEngine.createDefaultParameterNames(length);
}
return parameters;
@@ -1206,6 +1275,10 @@
public void setFlags(int flags) {
this.flags = flags;
}
+
+ public void setHasNoParameterNamesFromIndex(boolean hasNoParameterNamesFromIndex) {
+ this.hasNoParameterNamesFromIndex = hasNoParameterNamesFromIndex;
+ }
/**
* Returns the required completion proposals.
@@ -1312,7 +1385,23 @@
} catch(IllegalArgumentException e) {
// protection for invalid signature
if(this.parameterTypeNames != null) {
- this.parameterNames = createDefaultParameterNames(this.parameterTypeNames.length);
+ this.parameterNames = CompletionEngine.createDefaultParameterNames(this.parameterTypeNames.length);
+ } else {
+ this.parameterNames = null;
+ }
+ }
+ break;
+ case ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION:
+ try {
+ this.parameterNames = findConstructorParameterNames(
+ this.declarationPackageName,
+ this.declarationTypeName,
+ CharOperation.lastSegment(this.declarationTypeName, '.'),
+ Signature.getParameterTypes(this.originalSignature == null ? this.signature : this.originalSignature));
+ } catch(IllegalArgumentException e) {
+ // protection for invalid signature
+ if(this.parameterTypeNames != null) {
+ this.parameterNames = CompletionEngine.createDefaultParameterNames(this.parameterTypeNames.length);
} else {
this.parameterNames = null;
}
@@ -1329,7 +1418,23 @@
} catch(IllegalArgumentException e) {
// protection for invalid signature
if(this.parameterTypeNames != null) {
- this.parameterNames = createDefaultParameterNames(this.parameterTypeNames.length);
+ this.parameterNames = CompletionEngine.createDefaultParameterNames(this.parameterTypeNames.length);
+ } else {
+ this.parameterNames = null;
+ }
+ }
+ break;
+ case CONSTRUCTOR_INVOCATION:
+ try {
+ this.parameterNames = findConstructorParameterNames(
+ this.declarationPackageName,
+ this.declarationTypeName,
+ this.name,
+ Signature.getParameterTypes(this.originalSignature == null ? this.signature : this.originalSignature));
+ } catch(IllegalArgumentException e) {
+ // protection for invalid signature
+ if(this.parameterTypeNames != null) {
+ this.parameterNames = CompletionEngine.createDefaultParameterNames(this.parameterTypeNames.length);
} else {
this.parameterNames = null;
}
@@ -1345,7 +1450,7 @@
} catch(IllegalArgumentException e) {
// protection for invalid signature
if(this.parameterTypeNames != null) {
- this.parameterNames = createDefaultParameterNames(this.parameterTypeNames.length);
+ this.parameterNames = CompletionEngine.createDefaultParameterNames(this.parameterTypeNames.length);
} else {
this.parameterNames = null;
}
@@ -1623,6 +1728,12 @@
case CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER :
buffer.append("FIELD_REF_WITH_CASTED_RECEIVER"); //$NON-NLS-1$
break;
+ case CompletionProposal.CONSTRUCTOR_INVOCATION :
+ buffer.append("CONSTRUCTOR_INVOCATION"); //$NON-NLS-1$
+ break;
+ case CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION :
+ buffer.append("ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION"); //$NON-NLS-1$
+ break;
default :
buffer.append("PROPOSAL"); //$NON-NLS-1$
break;
Index: codeassist/org/eclipse/jdt/internal/codeassist/ISearchRequestor.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ISearchRequestor.java,v
retrieving revision 1.23
diff -u -r1.23 ISearchRequestor.java
--- codeassist/org/eclipse/jdt/internal/codeassist/ISearchRequestor.java 10 May 2006 18:03:52 -0000 1.23
+++ codeassist/org/eclipse/jdt/internal/codeassist/ISearchRequestor.java 14 Jan 2009 12:57:41 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -20,6 +20,18 @@
* to the raw name environment results before answering them to the UI.
*/
public interface ISearchRequestor {
+ public void acceptConstructor(
+ int modifiers,
+ char[] simpleTypeName,
+ int parameterCount,
+ char[] signature,
+ char[][] parameterTypes,
+ char[][] parameterNames,
+ int typeModifiers,
+ char[] packageName,
+ int extraFlags,
+ String path,
+ AccessRestriction access);
/**
* One result of the search consists of a new type.
*
Index: codeassist/org/eclipse/jdt/internal/codeassist/MissingTypesGuesser.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/MissingTypesGuesser.java,v
retrieving revision 1.5
diff -u -r1.5 MissingTypesGuesser.java
--- codeassist/org/eclipse/jdt/internal/codeassist/MissingTypesGuesser.java 27 Jun 2008 16:04:05 -0000 1.5
+++ codeassist/org/eclipse/jdt/internal/codeassist/MissingTypesGuesser.java 14 Jan 2009 12:57:41 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -462,7 +462,20 @@
isQualified ? CharOperation.concatWith(missingTypeName, '.') : null;
final ArrayList results = new ArrayList();
ISearchRequestor storage = new ISearchRequestor() {
-
+ public void acceptConstructor(
+ int modifiers,
+ char[] simpleTypeName,
+ int parameterCount,
+ char[] signature,
+ char[][] parameterTypes,
+ char[][] parameterNames,
+ int typeModifiers,
+ char[] packageName,
+ int extraFlags,
+ String path,
+ AccessRestriction access) {
+ // constructors aren't searched
+ }
public void acceptPackage(char[] packageName) {
// package aren't searched
}
Index: codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java,v
retrieving revision 1.151
diff -u -r1.151 SelectionEngine.java
--- codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java 29 Oct 2008 15:57:00 -0000 1.151
+++ codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java 14 Jan 2009 12:57:42 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -269,6 +269,21 @@
this.parser = new SelectionParser(problemReporter);
this.owner = owner;
}
+
+ public void acceptConstructor(
+ int modifiers,
+ char[] simpleTypeName,
+ int parameterCount,
+ char[] signature,
+ char[][] parameterTypes,
+ char[][] parameterNames,
+ int typeModifiers,
+ char[] packageName,
+ int extraFlags,
+ String path,
+ AccessRestriction access) {
+ // constructors aren't searched
+ }
public void acceptType(char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, int modifiers, AccessRestriction accessRestriction) {
char[] typeName = enclosingTypeNames == null ?
Index: codeassist/org/eclipse/jdt/internal/codeassist/CompletionElementNotifier.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionElementNotifier.java,v
retrieving revision 1.2
diff -u -r1.2 CompletionElementNotifier.java
--- codeassist/org/eclipse/jdt/internal/codeassist/CompletionElementNotifier.java 27 Jun 2008 16:04:03 -0000 1.2
+++ codeassist/org/eclipse/jdt/internal/codeassist/CompletionElementNotifier.java 14 Jan 2009 12:57:39 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008 IBM Corporation and others.
+ * Copyright (c) 2008, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -182,11 +182,11 @@
return typeParameterBounds;
}
- protected void notifySourceElementRequestor(AbstractMethodDeclaration methodDeclaration) {
+ protected void notifySourceElementRequestor(AbstractMethodDeclaration methodDeclaration, TypeDeclaration declaringType, ImportReference currentPackage) {
if (methodDeclaration instanceof CompletionOnMethodReturnType) return;
if (methodDeclaration instanceof CompletionOnMethodTypeParameter) return;
if (methodDeclaration instanceof CompletionOnMethodName) return;
- super.notifySourceElementRequestor(methodDeclaration);
+ super.notifySourceElementRequestor(methodDeclaration, declaringType, currentPackage);
}
public void notifySourceElementRequestor(CompilationUnitDeclaration parsedUnit, int sourceStart, int sourceEnd, boolean reportReference, HashtableOfObjectToInt sourceEndsMap, Map nodesToCategoriesMap) {
@@ -209,8 +209,8 @@
super.notifySourceElementRequestor(importReference, isPackage);
}
- protected void notifySourceElementRequestor(TypeDeclaration typeDeclaration, boolean notifyTypePresence, TypeDeclaration declaringType) {
+ protected void notifySourceElementRequestor(TypeDeclaration typeDeclaration, boolean notifyTypePresence, TypeDeclaration declaringType, ImportReference currentPackage) {
if (typeDeclaration instanceof CompletionOnAnnotationOfType) return;
- super.notifySourceElementRequestor(typeDeclaration, notifyTypePresence, declaringType);
+ super.notifySourceElementRequestor(typeDeclaration, notifyTypePresence, declaringType, currentPackage);
}
}
Index: model/org/eclipse/jdt/core/ICodeAssist.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICodeAssist.java,v
retrieving revision 1.36
diff -u -r1.36 ICodeAssist.java
--- model/org/eclipse/jdt/core/ICodeAssist.java 10 Oct 2008 07:28:58 -0000 1.36
+++ model/org/eclipse/jdt/core/ICodeAssist.java 14 Jan 2009 12:57:43 -0000
@@ -92,6 +92,26 @@
* An offset
of -1 indicates to code assist at the beginning of this
* compilation unit.
*
+ *
+ * If {@link IProgressMonitor} is not null
then some proposals which
+ * can be very long to compute are proposed. To avoid that the code assist operation
+ * take too much time a {@link IProgressMonitor} which automatically cancel the code
+ * assist operation when a specified amount of time is reached could be used.
+ *
+ *
+ * new IProgressMonitor() { + * private final static int TIMEOUT = 500; //ms + * private long endTime; + * public void beginTask(String name, int totalWork) { + * fEndTime= System.currentTimeMillis() + TIMEOUT; + * } + * public boolean isCanceled() { + * return endTime <= System.currentTimeMillis(); + * } + * ... + * }; + *+ *
* * @param offset the given offset position * @param requestor the given completion requestor @@ -180,6 +200,26 @@ * Note that if a working copy is empty, it will be as if the original compilation * unit had been deleted. *
+ *
+ * If {@link IProgressMonitor} is not null
then some proposals which
+ * can be very long to compute are proposed. To avoid that the code assist operation
+ * take too much time a {@link IProgressMonitor} which automatically cancel the code
+ * assist operation when a specified amount of time is reached could be used.
+ *
+ *
+ * new IProgressMonitor() { + * private final static int TIMEOUT = 500; //ms + * private long endTime; + * public void beginTask(String name, int totalWork) { + * fEndTime= System.currentTimeMillis() + TIMEOUT; + * } + * public boolean isCanceled() { + * return endTime <= System.currentTimeMillis(); + * } + * ... + * }; + *+ *
* * @param offset the given offset position * @param requestor the given completion requestor Index: model/org/eclipse/jdt/core/IType.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IType.java,v retrieving revision 1.65 diff -u -r1.65 IType.java --- model/org/eclipse/jdt/core/IType.java 10 Oct 2008 09:09:14 -0000 1.65 +++ model/org/eclipse/jdt/core/IType.java 14 Jan 2009 12:57:44 -0000 @@ -161,6 +161,26 @@ * If the type has access to its source code and the insertion position is valid, * then completion is performed against the source. Otherwise the completion is performed * against the type structure and the given locals variables. + *
+ * If {@link IProgressMonitor} is not null
then some proposals which
+ * can be very long to compute are proposed. To avoid that the code assist operation
+ * take too much time a {@link IProgressMonitor} which automatically cancel the code
+ * assist operation when a specified amount of time is reached could be used.
+ *
+ *
+ * new IProgressMonitor() { + * private final static int TIMEOUT = 500; //ms + * private long endTime; + * public void beginTask(String name, int totalWork) { + * fEndTime= System.currentTimeMillis() + TIMEOUT; + * } + * public boolean isCanceled() { + * return endTime <= System.currentTimeMillis(); + * } + * ... + * }; + *+ *
* * @param snippet the code snippet * @param insertion the position with in source where the snippet @@ -251,6 +271,26 @@ * then completion is performed against the source. Otherwise the completion is performed * against the type structure and the given locals variables. *
+ *
+ * If {@link IProgressMonitor} is not null
then some proposals which
+ * can be very long to compute are proposed. To avoid that the code assist operation
+ * take too much time a {@link IProgressMonitor} which automatically cancel the code
+ * assist operation when a specified amount of time is reached could be used.
+ *
+ *
+ * new IProgressMonitor() { + * private final static int TIMEOUT = 500; //ms + * private long endTime; + * public void beginTask(String name, int totalWork) { + * fEndTime= System.currentTimeMillis() + TIMEOUT; + * } + * public boolean isCanceled() { + * return endTime <= System.currentTimeMillis(); + * } + * ... + * }; + *+ *
*
* @param snippet the code snippet
* @param insertion the position with in source where the snippet
Index: model/org/eclipse/jdt/core/CompletionProposal.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionProposal.java,v
retrieving revision 1.46
diff -u -r1.46 CompletionProposal.java
--- model/org/eclipse/jdt/core/CompletionProposal.java 18 Sep 2008 14:06:39 -0000 1.46
+++ model/org/eclipse/jdt/core/CompletionProposal.java 14 Jan 2009 12:57:43 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -55,7 +55,7 @@
/**
* Completion is a declaration of an anonymous class.
* This kind of completion might occur in a context like
- * "new List^;"
and complete it to
+ * "new List(^;"
and complete it to
* "new List() {}"
.
*
* The following additional context information is available
@@ -792,6 +792,78 @@
* @since 3.4
*/
public static final int FIELD_REF_WITH_CASTED_RECEIVER = 25;
+
+ /**
+ * Completion is a reference to a constructor.
+ * This kind of completion might occur in a context like
+ * "new Lis"
and complete it to
+ * "new List();"
if List is a class that is not abstract.
+ *
+ * The following additional context information is available + * for this kind of completion proposal at little extra cost: + *
+ * This kind of proposal could require a long computation, so they are computed only if completion operation is called with a {@link IProgressMonitor} + * (eg. {@link ICodeAssist#codeComplete(int, CompletionRequestor, IProgressMonitor)}) + *
+ * + * @see #getKind() + * + * @since 3.5 + */ + public static final int CONSTRUCTOR_INVOCATION = 26; + + /** + * Completion is a reference of a constructor of an anonymous class. + * This kind of completion might occur in a context like + *"new Lis^;"
and complete it to
+ * "new List() {}"
if List is an interface or abstract class.
+ * + * The following additional context information is available + * for this kind of completion proposal at little extra cost: + *
+ * This kind of proposal could require a long computation, so they are computed only if completion operation is called with a {@link IProgressMonitor} + * (eg. {@link ICodeAssist#codeComplete(int, CompletionRequestor, IProgressMonitor)}) + *
+ * + * @see #getKind() + * + * @since 3.5 + */ + public static final int ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION = 27; /** * First valid completion kind. @@ -805,7 +877,7 @@ * * @since 3.1 */ - protected static final int LAST_KIND = FIELD_REF_WITH_CASTED_RECEIVER; + protected static final int LAST_KIND = ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION; /** * Creates a basic completion proposal. All instance @@ -1463,6 +1535,16 @@ *TYPE_REF
CONSTRUCTOR_INVOCATION
- The allowed required proposals for this kind are:
+ * TYPE_REF
ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION
- The allowed required proposals for this kind are:
+ * TYPE_REF
Index: model/org/eclipse/jdt/core/CompletionRequestor.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionRequestor.java,v retrieving revision 1.18 diff -u -r1.18 CompletionRequestor.java --- model/org/eclipse/jdt/core/CompletionRequestor.java 27 Jun 2008 16:04:01 -0000 1.18 +++ model/org/eclipse/jdt/core/CompletionRequestor.java 14 Jan 2009 12:57:43 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2008 IBM Corporation and others. + * Copyright (c) 2004, 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -174,7 +174,7 @@ return 0 != (this.requiredProposalAllowSet[proposalKind] & (1 << requiredProposalKind)); } - + /** * Sets whether a proposal of a given kind with a required proposal * of the given kind is allowed. Index: codeassist/org/eclipse/jdt/internal/codeassist/impl/Engine.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/Engine.java,v retrieving revision 1.63 diff -u -r1.63 Engine.java --- codeassist/org/eclipse/jdt/internal/codeassist/impl/Engine.java 22 Oct 2008 13:06:32 -0000 1.63 +++ codeassist/org/eclipse/jdt/internal/codeassist/impl/Engine.java 14 Jan 2009 12:57:43 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 IBM Corporation and others. + * Copyright (c) 2000, 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -65,8 +65,14 @@ */ public void accept(ICompilationUnit sourceUnit, AccessRestriction accessRestriction) { CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit); + + AssistParser assistParser = getParser(); + Object parserState = assistParser.becomeSimpleParser(); + CompilationUnitDeclaration parsedUnit = - getParser().dietParse(sourceUnit, result); + assistParser.dietParse(sourceUnit, result); + + assistParser.restoreAssistParser(parserState); this.lookupEnvironment.buildTypeBindings(parsedUnit, accessRestriction); this.lookupEnvironment.completeTypeBindings(parsedUnit, true); @@ -97,18 +103,13 @@ public abstract AssistParser getParser(); public void initializeImportCaches() { + if (this.currentPackageName == null) { + initializePackageCache(); + } + ImportBinding[] importBindings = this.unitScope.imports; int length = importBindings == null ? 0 : importBindings.length; - if (this.unitScope.fPackage != null) { - this.currentPackageName = CharOperation.concatWith(this.unitScope.fPackage.compoundName, '.'); - } else if (this.unitScope.referenceContext != null && - this.unitScope.referenceContext.currentPackage != null) { - this.currentPackageName = CharOperation.concatWith(this.unitScope.referenceContext.currentPackage.tokens, '.'); - } else { - this.currentPackageName = CharOperation.NO_CHAR; - } - for (int i = 0; i < length; i++) { ImportBinding importBinding = importBindings[i]; if(importBinding.onDemand) { @@ -133,6 +134,17 @@ this.importCachesInitialized = true; } + + public void initializePackageCache() { + if (this.unitScope.fPackage != null) { + this.currentPackageName = CharOperation.concatWith(this.unitScope.fPackage.compoundName, '.'); + } else if (this.unitScope.referenceContext != null && + this.unitScope.referenceContext.currentPackage != null) { + this.currentPackageName = CharOperation.concatWith(this.unitScope.referenceContext.currentPackage.tokens, '.'); + } else { + this.currentPackageName = CharOperation.NO_CHAR; + } + } protected boolean mustQualifyType( char[] packageName, Index: codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java,v retrieving revision 1.87 diff -u -r1.87 AssistParser.java --- codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java 23 Jul 2008 09:48:44 -0000 1.87 +++ codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java 14 Jan 2009 12:57:43 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 IBM Corporation and others. + * Copyright (c) 2000, 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -85,6 +85,21 @@ setStatementsRecovery(false); } public abstract char[] assistIdentifier(); + +/** + * The parser become a simple parser which behave like a Parser + * @return the state of the assist parser to be able to restore the assist parser state + */ +public Object becomeSimpleParser() { + return null; +} +/** + * Restore the parser as an assist parser + * @param parserState + */ +public void restoreAssistParser(Object parserState) { + //Do nothing +} public int bodyEnd(AbstractMethodDeclaration method){ return method.bodyEnd; } Index: model/org/eclipse/jdt/core/eval/IEvaluationContext.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/IEvaluationContext.java,v retrieving revision 1.26 diff -u -r1.26 IEvaluationContext.java --- model/org/eclipse/jdt/core/eval/IEvaluationContext.java 10 Oct 2008 07:28:58 -0000 1.26 +++ model/org/eclipse/jdt/core/eval/IEvaluationContext.java 14 Jan 2009 12:57:44 -0000 @@ -184,6 +184,26 @@ *
* Note that code completion does not involve evaluation. *
+ *
+ * If {@link IProgressMonitor} is not null
then some proposals which
+ * can be very long to compute are proposed. To avoid that the code assist operation
+ * take too much time a {@link IProgressMonitor} which automatically cancel the code
+ * assist operation when a specified amount of time is reached could be used.
+ *
+ *
+ * new IProgressMonitor() { + * private final static int TIMEOUT = 500; //ms + * private long endTime; + * public void beginTask(String name, int totalWork) { + * fEndTime= System.currentTimeMillis() + TIMEOUT; + * } + * public boolean isCanceled() { + * return endTime <= System.currentTimeMillis(); + * } + * ... + * }; + *+ *
* * @param codeSnippet the code snippet to complete in * @param position the character position in the code snippet to complete at, @@ -252,6 +272,26 @@ *
* Note that code completion does not involve evaluation. *
+ *
+ * If {@link IProgressMonitor} is not null
then some proposals which
+ * can be very long to compute are proposed. To avoid that the code assist operation
+ * take too much time a {@link IProgressMonitor} which automatically cancel the code
+ * assist operation when a specified amount of time is reached could be used.
+ *
+ *
+ * new IProgressMonitor() { + * private final static int TIMEOUT = 500; //ms + * private long endTime; + * public void beginTask(String name, int totalWork) { + * fEndTime= System.currentTimeMillis() + TIMEOUT; + * } + * public boolean isCanceled() { + * return endTime <= System.currentTimeMillis(); + * } + * ... + * }; + *+ *
*
* @param codeSnippet the code snippet to complete in
* @param position the character position in the code snippet to complete at,
Index: model/org/eclipse/jdt/internal/core/SearchableEnvironment.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java,v
retrieving revision 1.74
diff -u -r1.74 SearchableEnvironment.java
--- model/org/eclipse/jdt/internal/core/SearchableEnvironment.java 13 Oct 2008 20:06:01 -0000 1.74
+++ model/org/eclipse/jdt/internal/core/SearchableEnvironment.java 14 Jan 2009 12:57:44 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -23,6 +23,7 @@
import org.eclipse.jdt.internal.compiler.env.ISourceType;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
import org.eclipse.jdt.internal.core.search.BasicSearchEngine;
+import org.eclipse.jdt.internal.core.search.IRestrictedAccessConstructorRequestor;
import org.eclipse.jdt.internal.core.search.IRestrictedAccessTypeRequestor;
/**
@@ -447,6 +448,151 @@
convertSearchFilterToModelFilter(searchFor));
}
}
+
+ /**
+ * Must be used only by CompletionEngine.
+ * The progress monitor is used to be able to cancel completion operations
+ *
+ * Find constructor declarations that are defined
+ * in the current environment and whose name starts with the
+ * given prefix. The prefix is a qualified name separated by periods
+ * or a simple name (ex. java.util.V or V).
+ *
+ * The constructors found are passed to one of the following methods:
+ * ISearchRequestor.acceptConstructor(...)
+ */
+ public void findConstructorDeclarations(char[] prefix, boolean camelCaseMatch, final ISearchRequestor storage, IProgressMonitor monitor) {
+ try {
+ final String excludePath;
+ if (this.unitToSkip != null && this.unitToSkip instanceof IJavaElement) {
+ excludePath = ((IJavaElement) this.unitToSkip).getPath().toString();
+ } else {
+ excludePath = null;
+ }
+
+ int lastDotIndex = CharOperation.lastIndexOf('.', prefix);
+ char[] qualification, simpleName;
+ if (lastDotIndex < 0) {
+ qualification = null;
+ if (camelCaseMatch) {
+ simpleName = prefix;
+ } else {
+ simpleName = CharOperation.toLowerCase(prefix);
+ }
+ } else {
+ qualification = CharOperation.subarray(prefix, 0, lastDotIndex);
+ if (camelCaseMatch) {
+ simpleName = CharOperation.subarray(prefix, lastDotIndex + 1, prefix.length);
+ } else {
+ simpleName =
+ CharOperation.toLowerCase(
+ CharOperation.subarray(prefix, lastDotIndex + 1, prefix.length));
+ }
+ }
+
+ IProgressMonitor progressMonitor = new IProgressMonitor() {
+ boolean isCanceled = false;
+ public void beginTask(String name, int totalWork) {
+ // implements interface method
+ }
+ public void done() {
+ // implements interface method
+ }
+ public void internalWorked(double work) {
+ // implements interface method
+ }
+ public boolean isCanceled() {
+ return this.isCanceled;
+ }
+ public void setCanceled(boolean value) {
+ this.isCanceled = value;
+ }
+ public void setTaskName(String name) {
+ // implements interface method
+ }
+ public void subTask(String name) {
+ // implements interface method
+ }
+ public void worked(int work) {
+ // implements interface method
+ }
+ };
+
+ IRestrictedAccessConstructorRequestor constructorRequestor = new IRestrictedAccessConstructorRequestor() {
+ public void acceptConstructor(
+ int modifiers,
+ char[] simpleTypeName,
+ int parameterCount,
+ char[] signature,
+ char[][] parameterTypes,
+ char[][] parameterNames,
+ int typeModifiers,
+ char[] packageName,
+ int extraFlags,
+ String path,
+ AccessRestriction access) {
+ if (excludePath != null && excludePath.equals(path))
+ return;
+
+ storage.acceptConstructor(
+ modifiers,
+ simpleTypeName,
+ parameterCount,
+ signature,
+ parameterTypes,
+ parameterNames,
+ typeModifiers,
+ packageName,
+ extraFlags,
+ path,
+ access);
+ }
+ };
+
+ int matchRule = SearchPattern.R_PREFIX_MATCH;
+ if (camelCaseMatch) matchRule |= SearchPattern.R_CAMELCASE_MATCH;
+ if (monitor != null) {
+ found : while (true) { //the loop will finish if the search request ends or is cancelled
+ try {
+ new BasicSearchEngine(this.workingCopies).searchAllConstructorDeclarations(
+ qualification,
+ simpleName,
+ matchRule,
+ getSearchScope(),
+ constructorRequestor,
+ CANCEL_IF_NOT_READY_TO_SEARCH,
+ progressMonitor);
+ break found;
+ } catch (OperationCanceledException e) {
+ if (monitor.isCanceled()) {
+ throw e;
+ } else {
+ try {
+ Thread.sleep(50); // indexes are not ready. sleep 50ms and retry the search request
+ } catch (InterruptedException e1) {
+ // Do nothing
+ }
+ }
+ }
+ }
+ } else {
+ try {
+ new BasicSearchEngine(this.workingCopies).searchAllConstructorDeclarations(
+ qualification,
+ simpleName,
+ matchRule,
+ getSearchScope(),
+ constructorRequestor,
+ CANCEL_IF_NOT_READY_TO_SEARCH,
+ progressMonitor);
+ } catch (OperationCanceledException e) {
+ // Do nothing
+ }
+ }
+ } catch (JavaModelException e) {
+ // Do nothing
+ }
+ }
/**
* Returns all types whose name starts with the given (qualified) prefix
.
Index: search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java,v
retrieving revision 1.57
diff -u -r1.57 BasicSearchEngine.java
--- search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java 31 Oct 2008 16:53:33 -0000 1.57
+++ search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java 14 Jan 2009 12:57:45 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -430,6 +430,43 @@
}
return true;
}
+
+ boolean match(char[] patternName, char[] patternPackageName, int matchRule, char[] name, char[] packageName) {
+
+ boolean isCaseSensitive = (matchRule & SearchPattern.R_CASE_SENSITIVE) != 0;
+
+ if (patternPackageName != null && !CharOperation.equals(patternPackageName, packageName, true))
+ return false;
+
+ if (patternName != null) {
+ boolean isCamelCase = (matchRule & (SearchPattern.R_CAMELCASE_MATCH | SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH)) != 0;
+ int matchMode = matchRule & JavaSearchPattern.MATCH_MODE_MASK;
+ if (!isCaseSensitive && !isCamelCase) {
+ patternName = CharOperation.toLowerCase(patternName);
+ }
+ boolean matchFirstChar = !isCaseSensitive || patternName[0] == name[0];
+ switch(matchMode) {
+ case SearchPattern.R_EXACT_MATCH :
+ return matchFirstChar && CharOperation.equals(patternName, name, isCaseSensitive);
+ case SearchPattern.R_PREFIX_MATCH :
+ return matchFirstChar && CharOperation.prefixEquals(patternName, name, isCaseSensitive);
+ case SearchPattern.R_PATTERN_MATCH :
+ return CharOperation.match(patternName, name, isCaseSensitive);
+ case SearchPattern.R_REGEXP_MATCH :
+ // TODO (frederic) implement regular expression match
+ break;
+ case SearchPattern.R_CAMELCASE_MATCH:
+ if (matchFirstChar && CharOperation.camelCaseMatch(patternName, name, false)) {
+ return true;
+ }
+ return !isCaseSensitive && matchFirstChar && CharOperation.prefixEquals(patternName, name, false);
+ case SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH:
+ return matchFirstChar && CharOperation.camelCaseMatch(patternName, name, true);
+ }
+ }
+ return true;
+
+ }
boolean match(char patternTypeSuffix, char[] patternPkg, char[] patternTypeName, int matchRule, int typeKind, char[] pkg, char[] typeName) {
switch(patternTypeSuffix) {
@@ -505,6 +542,334 @@
}
findMatches(pattern, participants, scope, requestor, monitor);
}
+
+ public void searchAllConstructorDeclarations(
+ final char[] packageName,
+ final char[] typeName,
+ final int typeMatchRule,
+ IJavaSearchScope scope,
+ final IRestrictedAccessConstructorRequestor nameRequestor,
+ int waitingPolicy,
+ IProgressMonitor progressMonitor) throws JavaModelException {
+
+ // Validate match rule first
+ final int validatedTypeMatchRule = SearchPattern.validateMatchRule(typeName == null ? null : new String (typeName), typeMatchRule);
+
+ // Debug
+ if (VERBOSE) {
+ Util.verbose("BasicSearchEngine.searchAllTypeNames(char[], char[], int, int, IJavaSearchScope, IRestrictedAccessTypeRequestor, int, IProgressMonitor)"); //$NON-NLS-1$
+ Util.verbose(" - package name: "+(packageName==null?"null":new String(packageName))); //$NON-NLS-1$ //$NON-NLS-2$
+ Util.verbose(" - type name: "+(typeName==null?"null":new String(typeName))); //$NON-NLS-1$ //$NON-NLS-2$
+ Util.verbose(" - type match rule: "+getMatchRuleString(typeMatchRule)); //$NON-NLS-1$
+ if (validatedTypeMatchRule != typeMatchRule) {
+ Util.verbose(" - validated type match rule: "+getMatchRuleString(validatedTypeMatchRule)); //$NON-NLS-1$
+ }
+ Util.verbose(" - scope: "+scope); //$NON-NLS-1$
+ }
+ if (validatedTypeMatchRule == -1) return; // invalid match rule => return no results
+
+ // Create pattern
+ IndexManager indexManager = JavaModelManager.getIndexManager();
+ final ConstructorDeclarationPattern pattern = new ConstructorDeclarationPattern(
+ packageName,
+ typeName,
+ validatedTypeMatchRule);
+
+ // Get working copy path(s). Store in a single string in case of only one to optimize comparison in requestor
+ final HashSet workingCopyPaths = new HashSet();
+ String workingCopyPath = null;
+ ICompilationUnit[] copies = getWorkingCopies();
+ final int copiesLength = copies == null ? 0 : copies.length;
+ if (copies != null) {
+ if (copiesLength == 1) {
+ workingCopyPath = copies[0].getPath().toString();
+ } else {
+ for (int i = 0; i < copiesLength; i++) {
+ ICompilationUnit workingCopy = copies[i];
+ workingCopyPaths.add(workingCopy.getPath().toString());
+ }
+ }
+ }
+ final String singleWkcpPath = workingCopyPath;
+
+ // Index requestor
+ IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){
+ public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
+ // Filter unexpected types
+ ConstructorDeclarationPattern record = (ConstructorDeclarationPattern)indexRecord;
+
+ if ((record.extraFlags & ExtraFlags.IsMemberType) != 0) {
+ return true; // filter out member classes
+ }
+ if ((record.extraFlags & ExtraFlags.IsLocalType) != 0) {
+ return true; // filter out local and anonymous classes
+ }
+ switch (copiesLength) {
+ case 0:
+ break;
+ case 1:
+ if (singleWkcpPath.equals(documentPath)) {
+ return true; // filter out *the* working copy
+ }
+ break;
+ default:
+ if (workingCopyPaths.contains(documentPath)) {
+ return true; // filter out working copies
+ }
+ break;
+ }
+
+ // Accept document path
+ AccessRestriction accessRestriction = null;
+ if (access != null) {
+ // Compute document relative path
+ int pkgLength = (record.declaringPackageName==null || record.declaringPackageName.length==0) ? 0 : record.declaringPackageName.length+1;
+ int nameLength = record.declaringSimpleName==null ? 0 : record.declaringSimpleName.length;
+ char[] path = new char[pkgLength+nameLength];
+ int pos = 0;
+ if (pkgLength > 0) {
+ System.arraycopy(record.declaringPackageName, 0, path, pos, pkgLength-1);
+ CharOperation.replace(path, '.', '/');
+ path[pkgLength-1] = '/';
+ pos += pkgLength;
+ }
+ if (nameLength > 0) {
+ System.arraycopy(record.declaringSimpleName, 0, path, pos, nameLength);
+ pos += nameLength;
+ }
+ // Update access restriction if path is not empty
+ if (pos > 0) {
+ accessRestriction = access.getViolatedRestriction(path);
+ }
+ }
+ nameRequestor.acceptConstructor(
+ record.modifiers,
+ record.declaringSimpleName,
+ record.parameterCount,
+ record.signature,
+ record.parameterTypes,
+ record.parameterNames,
+ record.declaringTypeModifiers,
+ record.declaringPackageName,
+ record.extraFlags,
+ documentPath,
+ accessRestriction);
+ return true;
+ }
+ };
+
+ try {
+ if (progressMonitor != null) {
+ progressMonitor.beginTask(Messages.engine_searching, 1000);
+ }
+ // add type names from indexes
+ indexManager.performConcurrentJob(
+ new PatternSearchJob(
+ pattern,
+ getDefaultSearchParticipant(), // Java search only
+ scope,
+ searchRequestor),
+ waitingPolicy,
+ progressMonitor == null ? null : new SubProgressMonitor(progressMonitor, 1000-copiesLength));
+
+ // add type names from working copies
+ if (copies != null) {
+ for (int i = 0; i < copiesLength; i++) {
+ final ICompilationUnit workingCopy = copies[i];
+ if (!scope.encloses(workingCopy)) continue;
+ final String path = workingCopy.getPath().toString();
+ if (workingCopy.isConsistent()) {
+ IPackageDeclaration[] packageDeclarations = workingCopy.getPackageDeclarations();
+ char[] packageDeclaration = packageDeclarations.length == 0 ? CharOperation.NO_CHAR : packageDeclarations[0].getElementName().toCharArray();
+ IType[] allTypes = workingCopy.getAllTypes();
+ for (int j = 0, allTypesLength = allTypes.length; j < allTypesLength; j++) {
+ IType type = allTypes[j];
+ char[] simpleName = type.getElementName().toCharArray();
+ if (match(typeName, packageName, validatedTypeMatchRule, simpleName, packageDeclaration) && !type.isMember()) {
+
+ int extraFlags = ExtraFlags.getExtraFlags(type);
+
+ boolean hasConstructor = false;
+
+ IMethod[] methods = type.getMethods();
+ for (int k = 0; k < methods.length; k++) {
+ IMethod method = methods[k];
+ if (method.isConstructor()) {
+ hasConstructor = true;
+
+ String[] stringParameterNames = method.getParameterNames();
+ String[] stringParameterTypes = method.getParameterTypes();
+ int length = stringParameterNames.length;
+ char[][] parameterNames = new char[length][];
+ char[][] parameterTypes = new char[length][];
+ for (int l = 0; l < length; l++) {
+ parameterNames[l] = stringParameterNames[l].toCharArray();
+ parameterTypes[l] = Signature.toCharArray(Signature.getTypeErasure(stringParameterTypes[l]).toCharArray());
+ }
+
+ nameRequestor.acceptConstructor(
+ method.getFlags(),
+ simpleName,
+ parameterNames.length,
+ null,// signature is not used for source type
+ parameterTypes,
+ parameterNames,
+ type.getFlags(),
+ packageDeclaration,
+ extraFlags,
+ path,
+ null);
+ }
+ }
+
+ if (!hasConstructor) {
+ nameRequestor.acceptConstructor(
+ Flags.AccPublic,
+ simpleName,
+ -1,
+ null, // signature is not used for source type
+ CharOperation.NO_CHAR_CHAR,
+ CharOperation.NO_CHAR_CHAR,
+ type.getFlags(),
+ packageDeclaration,
+ extraFlags,
+ path,
+ null);
+ }
+ }
+ }
+ } else {
+ Parser basicParser = getParser();
+ org.eclipse.jdt.internal.compiler.env.ICompilationUnit unit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) workingCopy;
+ CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.compilerOptions.maxProblemsPerUnit);
+ CompilationUnitDeclaration parsedUnit = basicParser.dietParse(unit, compilationUnitResult);
+ if (parsedUnit != null) {
+ final char[] packageDeclaration = parsedUnit.currentPackage == null ? CharOperation.NO_CHAR : CharOperation.concatWith(parsedUnit.currentPackage.getImportName(), '.');
+ class AllConstructorDeclarationsVisitor extends ASTVisitor {
+ private TypeDeclaration[] declaringTypes = new TypeDeclaration[0];
+ private int declaringTypesPtr = -1;
+
+ private void endVisit(TypeDeclaration typeDeclaration) {
+ if (!hasConstructor(typeDeclaration) && typeDeclaration.enclosingType == null) {
+
+ if (match(typeName, packageName, validatedTypeMatchRule, typeDeclaration.name, packageDeclaration)) {
+ nameRequestor.acceptConstructor(
+ Flags.AccPublic,
+ typeName,
+ -1,
+ null, // signature is not used for source type
+ CharOperation.NO_CHAR_CHAR,
+ CharOperation.NO_CHAR_CHAR,
+ typeDeclaration.modifiers,
+ packageDeclaration,
+ ExtraFlags.getExtraFlags(typeDeclaration),
+ path,
+ null);
+ }
+ }
+
+ this.declaringTypes[this.declaringTypesPtr] = null;
+ this.declaringTypesPtr--;
+ }
+
+ public void endVisit(TypeDeclaration typeDeclaration, CompilationUnitScope s) {
+ endVisit(typeDeclaration);
+ }
+
+ public void endVisit(TypeDeclaration memberTypeDeclaration, ClassScope s) {
+ endVisit(memberTypeDeclaration);
+ }
+
+ private boolean hasConstructor(TypeDeclaration typeDeclaration) {
+ AbstractMethodDeclaration[] methods = typeDeclaration.methods;
+ int length = methods == null ? 0 : methods.length;
+ for (int j = 0; j < length; j++) {
+ if (methods[j].isConstructor()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope classScope) {
+ TypeDeclaration typeDeclaration = this.declaringTypes[this.declaringTypesPtr];
+ if (match(typeName, packageName, validatedTypeMatchRule, typeDeclaration.name, packageDeclaration)) {
+ Argument[] arguments = constructorDeclaration.arguments;
+ int length = arguments == null ? 0 : arguments.length;
+ char[][] parameterNames = new char[length][];
+ char[][] parameterTypes = new char[length][];
+ for (int l = 0; l < length; l++) {
+ Argument argument = arguments[l];
+ parameterNames[l] = argument.name;
+ if (argument.type instanceof SingleTypeReference) {
+ parameterTypes[l] = ((SingleTypeReference)argument.type).token;
+ } else {
+ parameterTypes[l] = CharOperation.concatWith(((QualifiedTypeReference)argument.type).tokens, '.');
+ }
+ }
+
+ TypeDeclaration enclosing = typeDeclaration.enclosingType;
+ char[][] enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
+ while (enclosing != null) {
+ enclosingTypeNames = CharOperation.arrayConcat(new char[][] {enclosing.name}, enclosingTypeNames);
+ if ((enclosing.bits & ASTNode.IsMemberType) != 0) {
+ enclosing = enclosing.enclosingType;
+ } else {
+ enclosing = null;
+ }
+ }
+
+ nameRequestor.acceptConstructor(
+ constructorDeclaration.modifiers,
+ typeName,
+ parameterNames.length,
+ null, // signature is not used for source type
+ parameterTypes,
+ parameterNames,
+ typeDeclaration.modifiers,
+ packageDeclaration,
+ ExtraFlags.getExtraFlags(typeDeclaration),
+ path,
+ null);
+ }
+ return false; // no need to find constructors from local/anonymous type
+ }
+ public boolean visit(TypeDeclaration typeDeclaration, BlockScope blockScope) {
+ return false;
+ }
+
+ private boolean visit(TypeDeclaration typeDeclaration) {
+ if(this.declaringTypes.length <= ++this.declaringTypesPtr) {
+ int length = this.declaringTypesPtr;
+ System.arraycopy(this.declaringTypes, 0, this.declaringTypes = new TypeDeclaration[length * 2 + 1], 0, length);
+ }
+ this.declaringTypes[this.declaringTypesPtr] = typeDeclaration;
+ return true;
+ }
+
+ public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope s) {
+ return visit(typeDeclaration);
+ }
+
+ public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope s) {
+ return visit(memberTypeDeclaration);
+ }
+ }
+ parsedUnit.traverse(new AllConstructorDeclarationsVisitor(), parsedUnit.scope);
+ }
+ }
+ if (progressMonitor != null) {
+ if (progressMonitor.isCanceled()) throw new OperationCanceledException();
+ progressMonitor.worked(1);
+ }
+ }
+ }
+ } finally {
+ if (progressMonitor != null) {
+ progressMonitor.done();
+ }
+ }
+ }
/**
* Searches for all secondary types in the given scope.
Index: search/org/eclipse/jdt/internal/core/search/matching/ConstructorPattern.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorPattern.java,v
retrieving revision 1.44
diff -u -r1.44 ConstructorPattern.java
--- search/org/eclipse/jdt/internal/core/search/matching/ConstructorPattern.java 18 Sep 2008 15:24:57 -0000 1.44
+++ search/org/eclipse/jdt/internal/core/search/matching/ConstructorPattern.java 14 Jan 2009 12:57:46 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -19,6 +19,8 @@
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.internal.compiler.ExtraFlags;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.core.index.EntryResult;
import org.eclipse.jdt.internal.core.index.Index;
import org.eclipse.jdt.internal.core.util.Util;
@@ -52,6 +54,162 @@
IJavaSearchConstants.THIS_REFERENCE |
IJavaSearchConstants.IMPLICIT_THIS_REFERENCE;
+
+/**
+ * Constructor entries are encoded as described
+ *
+ * Binary constructor for class
+ * TypeName '/' Arity '/' TypeModifers '/' PackageName '/' Signature '/' ParameterNamesopt '/' Modifiers
+ * Source constructor for class
+ * TypeName '/' Arity '/' TypeModifers '/' PackageName '/' ParameterTypes '/' ParameterNamesopt
+ * Constructor with 0 arity for class
+ * TypeName '/' 0 '/' TypeModifers '/' PackageName '/' Modifiers
+ * Constructor for enum, interface (annotation) and class with default constructor
+ * TypeName '/' # '/' TypeModifers '/' PackageName
+ * Constructor for member type
+ * TypeName '/' Arity '/' TypeModifers
+ *
+ * TypeModifiers contains some encoded extra information
+ * {@link ExtraFlags#IsMemberType}
+ * {@link ExtraFlags#HasNonPrivateStaticMemberTypes}
+ * {@link ExtraFlags#ParameterTypesStoredAsSignature}
+ */
+public static char[] createDeclarationIndexKey(
+ char[] typeName,
+ int argCount,
+ char[] signature,
+ char[][] parameterTypes,
+ char[][] parameterNames,
+ int modifiers,
+ char[] packageName,
+ int typeModifiers,
+ int extraFlags) {
+
+ char[] countChars;
+ char[] parameterTypesChars = null;
+ char[] parameterNamesChars = null;
+
+ if (argCount < 0) {
+ countChars = DEFAULT_CONSTRUCTOR;
+ } else {
+ countChars = argCount < 10
+ ? COUNTS[argCount]
+ : ("/" + String.valueOf(argCount)).toCharArray(); //$NON-NLS-1$
+
+ if (argCount > 0) {
+ if (signature == null) {
+ if (parameterTypes != null && parameterTypes.length == argCount) {
+ char[][] parameterTypeErasures = new char[argCount][];
+ for (int i = 0; i < parameterTypes.length; i++) {
+ parameterTypeErasures[i] = getTypeErasure(parameterTypes[i]);
+ }
+ parameterTypesChars = CharOperation.concatWith(parameterTypeErasures, PARAMETER_SEPARATOR);
+ }
+ } else {
+ extraFlags |= ExtraFlags.ParameterTypesStoredAsSignature;
+ }
+
+ if (parameterNames != null && parameterNames.length == argCount) {
+ parameterNamesChars = CharOperation.concatWith(parameterNames, PARAMETER_SEPARATOR);
+ }
+ }
+ }
+
+ boolean isMemberType = (extraFlags & ExtraFlags.IsMemberType) != 0;
+ boolean hasStoredParameterTypesAsSignature = (extraFlags & ExtraFlags.ParameterTypesStoredAsSignature) != 0;
+
+ int typeNameLength = typeName == null ? 0 : typeName.length;
+ int packageNameLength = packageName == null ? 0 : packageName.length;
+ int countCharsLength = countChars.length;
+ int parameterTypesLength = signature == null ? (parameterTypesChars == null ? 0 : parameterTypesChars.length): signature.length;
+ int parameterNamesLength = parameterNamesChars == null ? 0 : parameterNamesChars.length;
+
+ int resultLength = typeNameLength + countCharsLength + 3; // SEPARATOR=1 + TypeModifers=2
+ if (!isMemberType) {
+ resultLength += packageNameLength + 1; // SEPARATOR=1
+ if (argCount == 0 || hasStoredParameterTypesAsSignature) {
+ resultLength += 3; // SEPARATOR=1 + Modifiers=2
+ }
+
+ if (argCount > 0) {
+ resultLength += parameterTypesLength + parameterNamesLength + 2; //SEPARATOR=1 + SEPARATOR=1
+ }
+ }
+
+ char[] result = new char[resultLength];
+
+ int pos = 0;
+ if (typeNameLength > 0) {
+ System.arraycopy(typeName, 0, result, pos, typeNameLength);
+ pos += typeNameLength;
+ }
+
+ if (countCharsLength > 0) {
+ System.arraycopy(countChars, 0, result, pos, countCharsLength);
+ pos += countCharsLength;
+ }
+
+ int typeModifiersWithExtraFlags = typeModifiers | encodeExtraFlags(extraFlags);
+ result[pos++] = SEPARATOR;
+ result[pos++] = (char) typeModifiersWithExtraFlags;
+ result[pos++] = (char) (typeModifiersWithExtraFlags>>16);
+
+ if (!isMemberType) {
+ result[pos++] = SEPARATOR;
+ if (packageNameLength > 0) {
+ System.arraycopy(packageName, 0, result, pos, packageNameLength);
+ pos += packageNameLength;
+ }
+
+ if (argCount == 0) {
+ result[pos++] = SEPARATOR;
+ result[pos++] = (char) modifiers;
+ result[pos++] = (char) (modifiers>>16);
+ } else if (argCount > 0) {
+ result[pos++] = SEPARATOR;
+ if (parameterTypesLength > 0) {
+ if (signature == null) {
+ System.arraycopy(parameterTypesChars, 0, result, pos, parameterTypesLength);
+ } else {
+ System.arraycopy(CharOperation.replaceOnCopy(signature, SEPARATOR, '\\'), 0, result, pos, parameterTypesLength);
+ }
+ pos += parameterTypesLength;
+ }
+
+ result[pos++] = SEPARATOR;
+ if (parameterNamesLength > 0) {
+ System.arraycopy(parameterNamesChars, 0, result, pos, parameterNamesLength);
+ pos += parameterNamesLength;
+ }
+
+ if (hasStoredParameterTypesAsSignature) {
+ result[pos++] = SEPARATOR;
+ result[pos++] = (char) modifiers;
+ result[pos++] = (char) (modifiers>>16);
+ }
+ }
+
+ }
+
+ return result;
+}
+public static char[] createDefaultDeclarationIndexKey(
+ char[] typeName,
+ char[] packageName,
+ int typeModifiers,
+ int extraFlags) {
+ return createDeclarationIndexKey(
+ typeName,
+ -1, // used to identify default constructor
+ null,
+ null,
+ null,
+ 0, //
+ packageName,
+ typeModifiers,
+ extraFlags);
+}
+
/**
* Constructor entries are encoded as TypeName '/' Arity:
* e.g. 'X/0'
@@ -62,7 +220,79 @@
: ("/" + String.valueOf(argCount)).toCharArray(); //$NON-NLS-1$
return CharOperation.concat(typeName, countChars);
}
-
+static int decodeExtraFlags(int modifiersWithExtraFlags) {
+ int extraFlags = 0;
+
+ if ((modifiersWithExtraFlags & ASTNode.Bit28) != 0) {
+ extraFlags |= ExtraFlags.ParameterTypesStoredAsSignature;
+ }
+
+ if ((modifiersWithExtraFlags & ASTNode.Bit29) != 0) {
+ extraFlags |= ExtraFlags.IsLocalType;
+ }
+
+ if ((modifiersWithExtraFlags & ASTNode.Bit30) != 0) {
+ extraFlags |= ExtraFlags.IsMemberType;
+ }
+
+ if ((modifiersWithExtraFlags & ASTNode.Bit31) != 0) {
+ extraFlags |= ExtraFlags.HasNonPrivateStaticMemberTypes;
+ }
+
+ return extraFlags;
+}
+static int decodeModifers(int modifiersWithExtraFlags) {
+ return modifiersWithExtraFlags & ~(ASTNode.Bit31 | ASTNode.Bit30 | ASTNode.Bit29 | ASTNode.Bit28);
+}
+private static int encodeExtraFlags(int extraFlags) {
+ int encodedExtraFlags = 0;
+
+ if ((extraFlags & ExtraFlags.ParameterTypesStoredAsSignature) != 0) {
+ encodedExtraFlags |= ASTNode.Bit28;
+ }
+
+ if ((extraFlags & ExtraFlags.IsLocalType) != 0) {
+ encodedExtraFlags |= ASTNode.Bit29;
+ }
+
+ if ((extraFlags & ExtraFlags.IsMemberType) != 0) {
+ encodedExtraFlags |= ASTNode.Bit30;
+ }
+ if ((extraFlags & ExtraFlags.HasNonPrivateStaticMemberTypes) != 0) {
+ encodedExtraFlags |= ASTNode.Bit31;
+ }
+
+ return encodedExtraFlags;
+}
+private static char[] getTypeErasure(char[] typeName) {
+ int index;
+ if ((index = CharOperation.indexOf('<', typeName)) == -1) return typeName;
+
+ int length = typeName.length;
+ char[] typeErasurename = new char[length - 2];
+
+ System.arraycopy(typeName, 0, typeErasurename, 0, index);
+
+ int depth = 1;
+ for (int i = index + 1; i < length; i++) {
+ switch (typeName[i]) {
+ case '<':
+ depth++;
+ break;
+ case '>':
+ depth--;
+ break;
+ default:
+ if (depth == 0) {
+ typeErasurename[index++] = typeName[i];
+ }
+ break;
+ }
+ }
+
+ System.arraycopy(typeErasurename, 0, typeErasurename = new char[index], 0, index);
+ return typeErasurename;
+}
ConstructorPattern(int matchRule) {
super(CONSTRUCTOR_PATTERN, matchRule);
}
@@ -225,21 +455,31 @@
}
if (hasConstructorArguments()) this.mustResolve = true;
}
+
public void decodeIndexKey(char[] key) {
int last = key.length - 1;
- this.parameterCount = 0;
- this.declaringSimpleName = null;
- int power = 1;
- for (int i=last; i>=0; i--) {
- if (key[i] == SEPARATOR) {
- System.arraycopy(key, 0, this.declaringSimpleName = new char[i], 0, i);
- break;
- }
- if (i == last) {
- this.parameterCount = key[i] - '0';
- } else {
- power *= 10;
- this.parameterCount += power * (key[i] - '0');
+ int slash = CharOperation.indexOf(SEPARATOR, key, 0);
+ this.declaringSimpleName = CharOperation.subarray(key, 0, slash);
+
+ int start = slash + 1;
+ slash = CharOperation.indexOf(SEPARATOR, key, start);
+ if (slash != -1) {
+ last = slash - 1;
+ }
+
+ boolean isDefaultConstructor = key[last] == '#';
+ if (isDefaultConstructor) {
+ this.parameterCount = -1;
+ } else {
+ this.parameterCount = 0;
+ int power = 1;
+ for (int i = last; i >= start; i--) {
+ if (i == last) {
+ this.parameterCount = key[i] - '0';
+ } else {
+ power *= 10;
+ this.parameterCount += power * (key[i] - '0');
+ }
}
}
}
@@ -262,7 +502,8 @@
public boolean matchesDecodedKey(SearchPattern decodedPattern) {
ConstructorPattern pattern = (ConstructorPattern) decodedPattern;
- return (this.parameterCount == pattern.parameterCount || this.parameterCount == -1 || this.varargs)
+ return pattern.parameterCount != -1
+ && (this.parameterCount == pattern.parameterCount || this.parameterCount == -1 || this.varargs)
&& matchesName(this.declaringSimpleName, pattern.declaringSimpleName);
}
protected boolean mustResolve() {
@@ -280,12 +521,11 @@
switch(getMatchMode()) {
case R_EXACT_MATCH :
- if (this.declaringSimpleName != null && this.parameterCount >= 0 && !this.varargs)
+ if (this.declaringSimpleName != null && this.parameterCount >= 0 && !this.varargs) {
key = createIndexKey(this.declaringSimpleName, this.parameterCount);
- else { // do a prefix query with the declaringSimpleName
- matchRule &= ~R_EXACT_MATCH;
- matchRule |= R_PREFIX_MATCH;
}
+ matchRule &= ~R_EXACT_MATCH;
+ matchRule |= R_PREFIX_MATCH;
break;
case R_PREFIX_MATCH :
// do a prefix query with the declaringSimpleName
@@ -295,6 +535,7 @@
key = createIndexKey(this.declaringSimpleName == null ? ONE_STAR : this.declaringSimpleName, this.parameterCount);
else if (this.declaringSimpleName != null && this.declaringSimpleName[this.declaringSimpleName.length - 1] != '*')
key = CharOperation.concat(this.declaringSimpleName, ONE_STAR, SEPARATOR);
+ key = CharOperation.concat(key, ONE_STAR);
// else do a pattern query with just the declaringSimpleName
break;
case R_REGEXP_MATCH :
Index: search/org/eclipse/jdt/internal/core/search/matching/ConstructorDeclarationPattern.java
===================================================================
RCS file: search/org/eclipse/jdt/internal/core/search/matching/ConstructorDeclarationPattern.java
diff -N search/org/eclipse/jdt/internal/core/search/matching/ConstructorDeclarationPattern.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ search/org/eclipse/jdt/internal/core/search/matching/ConstructorDeclarationPattern.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import java.io.IOException;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.internal.compiler.ExtraFlags;
+import org.eclipse.jdt.internal.core.index.EntryResult;
+import org.eclipse.jdt.internal.core.index.Index;
+
+public class ConstructorDeclarationPattern extends ConstructorPattern {
+ private static final char[][] EXT_DECL_CATEGORIES = {CONSTRUCTOR_DECL};
+
+ public int extraFlags;
+
+ public int declaringTypeModifiers;
+ public char[] declaringPackageName;
+
+ public int modifiers;
+ public char[] signature;
+ public char[][] parameterTypes;
+ public char[][] parameterNames;
+
+public ConstructorDeclarationPattern(char[] declaringPackageName, char[] declaringSimpleName, int matchRule) {
+ this(matchRule);
+ this.declaringSimpleName = (this.isCaseSensitive || this.isCamelCase) ? declaringSimpleName : CharOperation.toLowerCase(declaringSimpleName);
+ this.declaringPackageName = declaringPackageName;
+ this.findDeclarations = true;
+ this.findReferences = false;
+ this.parameterCount = -1;
+ this.mustResolve = false;
+}
+
+ConstructorDeclarationPattern(int matchRule) {
+ super(matchRule);
+}
+public void decodeIndexKey(char[] key) {
+ int last = key.length - 1;
+ int slash = CharOperation.indexOf(SEPARATOR, key, 0);
+ this.declaringSimpleName = CharOperation.subarray(key, 0, slash);
+
+ int start = slash + 1;
+ slash = CharOperation.indexOf(SEPARATOR, key, start);
+ last = slash - 1;
+
+ boolean isDefaultConstructor = key[last] == '#';
+ if (isDefaultConstructor) {
+ this.parameterCount = -1;
+ } else {
+ this.parameterCount = 0;
+ int power = 1;
+ for (int i = last; i >= start; i--) {
+ if (i == last) {
+ this.parameterCount = key[i] - '0';
+ } else {
+ power *= 10;
+ this.parameterCount += power * (key[i] - '0');
+ }
+ }
+ }
+
+ slash = slash + 3;
+ last = slash - 1;
+
+ int typeModifiersWithExtraFlags = key[last-1] + (key[last]<<16);
+ this.declaringTypeModifiers = decodeModifers(typeModifiersWithExtraFlags);
+ this.extraFlags = decodeExtraFlags(typeModifiersWithExtraFlags);
+
+ boolean isMemberType = (this.extraFlags & ExtraFlags.IsMemberType) != 0;
+
+ if (!isMemberType) {
+ start = slash + 1;
+ if (this.parameterCount == -1) {
+ slash = key.length;
+ last = slash - 1;
+ } else {
+ slash = CharOperation.indexOf(SEPARATOR, key, start);
+ }
+ last = slash - 1;
+
+ this.declaringPackageName = CharOperation.subarray(key, start, slash);
+
+ start = slash + 1;
+ if (this.parameterCount == 0) {
+ slash = slash + 3;
+ last = slash - 1;
+
+ this.modifiers = key[last-1] + (key[last]<<16);
+ } else if (this.parameterCount > 0){
+ slash = CharOperation.indexOf(SEPARATOR, key, start);
+ last = slash - 1;
+
+ boolean hasParameterStoredAsSignature = (this.extraFlags & ExtraFlags.ParameterTypesStoredAsSignature) != 0;
+ if (hasParameterStoredAsSignature) {
+ this.signature = CharOperation.subarray(key, start, slash);
+ CharOperation.replace(this.signature , '\\', SEPARATOR);
+
+ start = slash + 1;
+ slash = CharOperation.indexOf(SEPARATOR, key, start);
+ } else {
+ this.parameterTypes = CharOperation.splitOn(PARAMETER_SEPARATOR, key, start, slash);
+
+ start = slash + 1;
+ slash = key.length;
+ }
+ last = slash - 1;
+
+ if (slash != start) {
+ this.parameterNames = CharOperation.splitOn(PARAMETER_SEPARATOR, key, start, slash);
+ }
+
+ if (hasParameterStoredAsSignature) {
+ slash = slash + 3;
+ last = slash - 1;
+
+ this.modifiers = key[last-1] + (key[last]<<16);
+ }
+ }
+ }
+
+ removeInternalFlags(); // remove internal flags
+}
+
+public SearchPattern getBlankPattern() {
+ return new ConstructorDeclarationPattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
+}
+public char[][] getIndexCategories() {
+ return EXT_DECL_CATEGORIES;
+}
+public boolean matchesDecodedKey(SearchPattern decodedPattern) {
+ ConstructorDeclarationPattern pattern = (ConstructorDeclarationPattern) decodedPattern;
+
+ // only top level types
+ if ((pattern.extraFlags & ExtraFlags.IsMemberType) != 0) return false;
+
+ // check package - exact match only
+ if (this.declaringPackageName != null && !CharOperation.equals(this.declaringPackageName, pattern.declaringPackageName, true))
+ return false;
+
+ return (this.parameterCount == pattern.parameterCount || this.parameterCount == -1 || this.varargs)
+ && matchesName(this.declaringSimpleName, pattern.declaringSimpleName);
+}
+public EntryResult[] queryIn(Index index) throws IOException {
+ char[] key = this.declaringSimpleName; // can be null
+ int matchRule = getMatchRule();
+
+ switch(getMatchMode()) {
+ case R_EXACT_MATCH :
+ if (this.declaringSimpleName != null && this.parameterCount >= 0 && !this.varargs) {
+ key = createIndexKey(this.declaringSimpleName, this.parameterCount);
+ }
+ matchRule &= ~R_EXACT_MATCH;
+ matchRule |= R_PREFIX_MATCH;
+ break;
+ case R_PREFIX_MATCH :
+ // do a prefix query with the declaringSimpleName
+ break;
+ case R_PATTERN_MATCH :
+ if (this.parameterCount >= 0 && !this.varargs)
+ key = createIndexKey(this.declaringSimpleName == null ? ONE_STAR : this.declaringSimpleName, this.parameterCount);
+ else if (this.declaringSimpleName != null && this.declaringSimpleName[this.declaringSimpleName.length - 1] != '*')
+ key = CharOperation.concat(this.declaringSimpleName, ONE_STAR, SEPARATOR);
+ key = CharOperation.concat(key, ONE_STAR);
+ // else do a pattern query with just the declaringSimpleName
+ break;
+ case R_REGEXP_MATCH :
+ // TODO (frederic) implement regular expression match
+ break;
+ case R_CAMELCASE_MATCH:
+ case R_CAMELCASE_SAME_PART_COUNT_MATCH:
+ // do a prefix query with the declaringSimpleName
+ break;
+ }
+
+ return index.query(getIndexCategories(), key, matchRule); // match rule is irrelevant when the key is null
+}
+private void removeInternalFlags() {
+ this.extraFlags = this.extraFlags & ~ExtraFlags.ParameterTypesStoredAsSignature; // ParameterTypesStoredAsSignature is an internal flags only used to decode key
+}
+}
Index: search/org/eclipse/jdt/internal/core/search/IRestrictedAccessConstructorRequestor.java
===================================================================
RCS file: search/org/eclipse/jdt/internal/core/search/IRestrictedAccessConstructorRequestor.java
diff -N search/org/eclipse/jdt/internal/core/search/IRestrictedAccessConstructorRequestor.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ search/org/eclipse/jdt/internal/core/search/IRestrictedAccessConstructorRequestor.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search;
+
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+
+/**
+ * A IRestrictedAccessConstructorRequestor
collects search results from a searchAllConstructorDeclarations
+ * query to a SearchBasicEngine
providing restricted access information of declaring type when a constructor is accepted.
+ */
+public interface IRestrictedAccessConstructorRequestor {
+
+ public void acceptConstructor(
+ int modifiers,
+ char[] simpleTypeName,
+ int parameterCount,
+ char[] signature,
+ char[][] parameterTypes,
+ char[][] parameterNames,
+ int typeModifiers,
+ char[] packageName,
+ int extraFlags,
+ String path,
+ AccessRestriction access);
+
+}
Index: model/org/eclipse/jdt/internal/compiler/ExtraFlags.java
===================================================================
RCS file: model/org/eclipse/jdt/internal/compiler/ExtraFlags.java
diff -N model/org/eclipse/jdt/internal/compiler/ExtraFlags.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ model/org/eclipse/jdt/internal/compiler/ExtraFlags.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler;
+
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.env.IBinaryNestedType;
+
+public final class ExtraFlags {
+ public final static int HasNonPrivateStaticMemberTypes = 0x0001;
+ public final static int IsMemberType = 0x0002;
+ public final static int IsLocalType = 0x0004;
+
+ //internal flags
+ public final static int ParameterTypesStoredAsSignature = 0x0010;
+
+ public static int getExtraFlags(ClassFileReader reader) {
+ int extraFlags = 0;
+
+ if (reader.isNestedType()) {
+ extraFlags |= ExtraFlags.IsMemberType;
+ }
+
+ if (reader.isLocal()) {
+ extraFlags |= ExtraFlags.IsLocalType;
+ }
+
+ IBinaryNestedType[] memberTypes = reader.getMemberTypes();
+ int memberTypeCounter = memberTypes == null ? 0 : memberTypes.length;
+ if (memberTypeCounter > 0) {
+ done : for (int i = 0; i < memberTypeCounter; i++) {
+ int modifiers = memberTypes[i].getModifiers();
+ // if the member type is static and not private
+ if ((modifiers & ClassFileConstants.AccStatic) != 0 && (modifiers & ClassFileConstants.AccPrivate) == 0) {
+ extraFlags |= ExtraFlags.HasNonPrivateStaticMemberTypes;
+ break done;
+ }
+ }
+
+ }
+
+ return extraFlags;
+ }
+
+ public static int getExtraFlags(IType type) throws JavaModelException {
+ int extraFlags = 0;
+
+ if (type.isMember()) {
+ extraFlags |= ExtraFlags.IsMemberType;
+ }
+
+ if (type.isLocal()) {
+ extraFlags |= ExtraFlags.IsLocalType;
+ }
+
+ IType[] memberTypes = type.getTypes();
+ int memberTypeCounter = memberTypes == null ? 0 : memberTypes.length;
+ if (memberTypeCounter > 0) {
+ done : for (int i = 0; i < memberTypeCounter; i++) {
+ int flags = memberTypes[i].getFlags();
+ // if the member type is static and not private
+ if ((flags & ClassFileConstants.AccStatic) != 0 && (flags & ClassFileConstants.AccPrivate) == 0 ) {
+ extraFlags |= ExtraFlags.HasNonPrivateStaticMemberTypes;
+ break done;
+ }
+ }
+ }
+
+ return extraFlags;
+ }
+
+ public static int getExtraFlags(TypeDeclaration typeDeclaration) {
+ int extraFlags = 0;
+
+ if (typeDeclaration.enclosingType != null) {
+ extraFlags |= ExtraFlags.IsMemberType;
+ }
+ TypeDeclaration[] memberTypes = typeDeclaration.memberTypes;
+ int memberTypeCounter = memberTypes == null ? 0 : memberTypes.length;
+ if (memberTypeCounter > 0) {
+ done : for (int i = 0; i < memberTypeCounter; i++) {
+ int modifiers = memberTypes[i].modifiers;
+ // if the member type is static and not private
+ if ((modifiers & ClassFileConstants.AccStatic) != 0 && (modifiers & ClassFileConstants.AccPrivate) == 0) {
+ extraFlags |= ExtraFlags.HasNonPrivateStaticMemberTypes;
+ break done;
+ }
+ }
+ }
+
+ return extraFlags;
+ }
+}
#P org.eclipse.jdt.core.tests.model
Index: src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java,v
retrieving revision 1.162
diff -u -r1.162 JavaSearchBugsTests.java
--- src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java 23 Oct 2008 17:39:32 -0000 1.162
+++ src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java 14 Jan 2009 12:57:54 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -160,6 +160,157 @@
);
}
+public void testBug6930_AllConstructorDeclarations01() throws Exception {
+ this.workingCopies = new ICompilationUnit[2];
+ this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/p6930/AllConstructorDeclarations01.java",
+ "package p6930;\n" +
+ "public class AllConstructorDeclarations01 {\n" +
+ " public AllConstructorDeclarations01() {}\n" +
+ " public AllConstructorDeclarations01(Object o) {}\n" +
+ " public AllConstructorDeclarations01(Object o, String s) {}\n" +
+ "}\n"
+ );
+
+ this.workingCopies[1] = getWorkingCopy("/JavaSearchBugs/src/p6930/AllConstructorDeclarations01b.java",
+ "package p6930;\n" +
+ "public class AllConstructorDeclarations01b {\n" +
+ "}\n"
+ );
+
+ ConstructorDeclarationsCollector requestor = new ConstructorDeclarationsCollector();
+ searchAllConstructorDeclarations("AllConstructorDeclarations", SearchPattern.R_PREFIX_MATCH, requestor);
+ assertSearchResults(
+ "p6930.AllConstructorDeclarations01#AllConstructorDeclarations01()\n" +
+ "p6930.AllConstructorDeclarations01#AllConstructorDeclarations01(Object o)\n" +
+ "p6930.AllConstructorDeclarations01#AllConstructorDeclarations01(Object o,String s)\n" +
+ "p6930.AllConstructorDeclarations01b#AllConstructorDeclarations01b()*",
+ requestor
+ );
+}
+
+public void testBug6930_AllConstructorDeclarations02() throws Exception {
+ try {
+ IJavaProject p = createJavaProject("P", new String[] {}, new String[] {"/P/lib6930.jar"}, "");
+
+ createJar(new String[] {
+ "p6930/AllConstructorDeclarations02.java",
+ "package p6930;\n" +
+ "public class AllConstructorDeclarations02 {\n" +
+ " public AllConstructorDeclarations02() {}\n" +
+ " public AllConstructorDeclarations02(Object o) {}\n" +
+ " public AllConstructorDeclarations02(Object o, String s) {}\n" +
+ "}",
+ "p6930/AllConstructorDeclarations02b.java",
+ "package p6930;\n" +
+ "public class AllConstructorDeclarations02b {\n" +
+ "}"
+ }, p.getProject().getLocation().append("lib6930.jar").toOSString());
+ refresh(p);
+
+ ConstructorDeclarationsCollector requestor = new ConstructorDeclarationsCollector();
+ searchAllConstructorDeclarations("AllConstructorDeclarations", SearchPattern.R_PREFIX_MATCH, requestor);
+ assertSearchResults(
+ "p6930.AllConstructorDeclarations02#AllConstructorDeclarations02()\n" +
+ "p6930.AllConstructorDeclarations02#AllConstructorDeclarations02(java.lang.Object o)\n" +
+ "p6930.AllConstructorDeclarations02#AllConstructorDeclarations02(java.lang.Object o,java.lang.String s)\n" +
+ "p6930.AllConstructorDeclarations02b#AllConstructorDeclarations02b()",
+ requestor
+ );
+ } finally {
+ deleteProject("P");
+ }
+}
+
+public void testBug6930_AllConstructorDeclarations03() throws Exception {
+ try {
+ IJavaProject p = createJavaProject("P", new String[] {"src"}, new String[] {}, "bin");
+
+ createFolder("/P/src/p6930");
+
+ createFile(
+ "/P/src/p6930/AllConstructorDeclarations03.java",
+ "package p6930;\n" +
+ "public class AllConstructorDeclarations03 {\n" +
+ " public AllConstructorDeclarations03() {}\n" +
+ " public AllConstructorDeclarations03(Object o) {}\n" +
+ " public AllConstructorDeclarations03(Object o, String s) {}\n" +
+ "}");
+
+ createFile(
+ "/P/src/p6930/AllConstructorDeclarations03b.java",
+ "package p6930;\n" +
+ "public class AllConstructorDeclarations03b {\n" +
+ "}");
+ refresh(p);
+
+ ConstructorDeclarationsCollector requestor = new ConstructorDeclarationsCollector();
+ searchAllConstructorDeclarations("AllConstructorDeclarations", SearchPattern.R_PREFIX_MATCH, requestor);
+ assertSearchResults(
+ "p6930.AllConstructorDeclarations03#AllConstructorDeclarations03()\n" +
+ "p6930.AllConstructorDeclarations03#AllConstructorDeclarations03(Object o)\n" +
+ "p6930.AllConstructorDeclarations03#AllConstructorDeclarations03(Object o,String s)\n" +
+ "p6930.AllConstructorDeclarations03b#AllConstructorDeclarations03b()*",
+ requestor
+ );
+ } finally {
+ deleteProject("P");
+ }
+}
+
+public void testBug6930_AllConstructorDeclarations04() throws Exception {
+ try {
+ IJavaProject p = createJavaProject("P", new String[] {}, new String[] {"/P/lib6930.jar"}, "","1.5");
+
+ createJar(
+ new String[] {
+ "p6930/AllConstructorDeclarations04.java",
+ "package p6930;\n" +
+ "public class AllConstructorDeclarations04 {\n" +
+ " public AllConstructorDeclarations04(java.util.Collection