### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core.tests.model Index: src/org/eclipse/jdt/core/tests/model/CompletionTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests.java,v retrieving revision 1.133 diff -u -r1.133 CompletionTests.java --- src/org/eclipse/jdt/core/tests/model/CompletionTests.java 3 Nov 2006 12:52:05 -0000 1.133 +++ src/org/eclipse/jdt/core/tests/model/CompletionTests.java 6 Nov 2006 16:41:56 -0000 @@ -10488,6 +10488,32 @@ "variable[VARIABLE_DECLARATION]{variable, null, I, variable, null, "+(R_DEFAULT + R_INTERESTING + R_NAME_FIRST_SUFFIX + R_NAME_FIRST_PREFIX + R_NAME_LESS_NEW_CHARACTERS + R_CASE + R_NON_RESTRICTED)+"}", requestor.getResults()); } +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=162968 +public void testCompletionVariableName34() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/test/Test.java", + "package test;\n"+ + "public class Test {\n"+ + " int vDefined;\n"+ + " void bar() {\n"+ + " /**/int v\n"+ + " System.out.println(vUnknown);\n"+ + " System.out.println(vUnknown);\n"+ + " }\n"+ + "}"); + + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + String str = this.workingCopies[0].getSource(); + String completeBehind = "/**/int v"; + int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + + assertResults( + "vI[VARIABLE_DECLARATION]{vI, null, I, vI, null, "+(R_DEFAULT + R_INTERESTING + R_CASE + R_NON_RESTRICTED)+"}\n"+ + "vUnknown[VARIABLE_DECLARATION]{vUnknown, null, I, vUnknown, null, "+(R_DEFAULT + R_INTERESTING + R_NAME_FIRST_SUFFIX + R_NAME_FIRST_PREFIX + R_NAME_LESS_NEW_CHARACTERS + R_CASE + R_NON_RESTRICTED)+"}", + requestor.getResults()); +} public void testCompletionNonEmptyToken1() throws JavaModelException { CompletionTestsRequestor requestor = new CompletionTestsRequestor(); ICompilationUnit cu= getCompilationUnit("Completion", "src", "", "CompletionNonEmptyToken1.java"); #P org.eclipse.jdt.core 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.307 diff -u -r1.307 CompletionEngine.java --- codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java 26 Oct 2006 01:24:52 -0000 1.307 +++ codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java 6 Nov 2006 16:42:02 -0000 @@ -1280,6 +1280,20 @@ if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) { LocalDeclaration variable = (LocalDeclaration) astNode; + int kind; + if (variable instanceof CompletionOnLocalName){ + this.completionToken = ((CompletionOnLocalName) variable).realName; + kind = LOCAL; + } else { + CompletionOnArgumentName arg = (CompletionOnArgumentName) variable; + this.completionToken = arg.realName; + kind = arg.isCatchArgument ? LOCAL : ARGUMENT; + } + + char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, variable); + + char[][] forbiddenNames = findVariableFromUnresolvedReference(variable, (BlockScope)scope, alreadyDefinedName); + LocalVariableBinding[] locals = ((BlockScope)scope).locals; char[][] discouragedNames = new char[locals.length][]; int localCount = 0; @@ -1288,18 +1302,10 @@ discouragedNames[localCount++] = locals[i].name; } } + System.arraycopy(discouragedNames, 0, discouragedNames = new char[localCount][], 0, localCount); - if (variable instanceof CompletionOnLocalName){ - this.completionToken = ((CompletionOnLocalName) variable).realName; - char[][] forbiddenNames = findVariableFromUnresolvedReference(variable, (BlockScope)scope, discouragedNames); - findVariableNames(this.completionToken, variable.type, discouragedNames, forbiddenNames, LOCAL, variable.modifiers); - } else { - CompletionOnArgumentName arg = (CompletionOnArgumentName) variable; - this.completionToken = arg.realName; - char[][] forbiddenNames = findVariableFromUnresolvedReference(variable, (BlockScope)scope, discouragedNames); - findVariableNames(this.completionToken, variable.type, discouragedNames, forbiddenNames, arg.isCatchArgument ? LOCAL : ARGUMENT, variable.modifiers); - } + findVariableNames(this.completionToken, variable.type, discouragedNames, forbiddenNames, kind, variable.modifiers); } } else if (astNode instanceof CompletionOnKeyword) { if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { @@ -6497,6 +6503,156 @@ this.endPosition = end + 1; } } + private char[][] computeAlreadyDefinedName( + BlockScope scope, + InvocationSite invocationSite) { + ArrayList result = new ArrayList(); + + boolean staticsOnly = false; + + Scope currentScope = scope; + + done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found + + switch (currentScope.kind) { + + case Scope.METHOD_SCOPE : + // handle the error case inside an explicit constructor call (see MethodScope>>findField) + MethodScope methodScope = (MethodScope) currentScope; + staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall; + + case Scope.BLOCK_SCOPE : + BlockScope blockScope = (BlockScope) currentScope; + + next : for (int i = 0, length = blockScope.locals.length; i < length; i++) { + LocalVariableBinding local = blockScope.locals[i]; + + if (local == null) + break next; + + if (local.isSecret()) + continue next; + + result.add(local.name); + } + break; + + case Scope.CLASS_SCOPE : + ClassScope classScope = (ClassScope) currentScope; + SourceTypeBinding enclosingType = classScope.referenceContext.binding; + computeAlreadyDefinedName( + enclosingType, + classScope, + staticsOnly, + invocationSite, + result); + staticsOnly |= enclosingType.isStatic(); + break; + + case Scope.COMPILATION_UNIT_SCOPE : + break done1; + } + currentScope = currentScope.parent; + } + + if (result.size() == 0) return CharOperation.NO_CHAR_CHAR; + + return (char[][])result.toArray(new char[result.size()][]); + } + + private void computeAlreadyDefinedName( + SourceTypeBinding receiverType, + ClassScope scope, + boolean onlyStaticFields, + InvocationSite invocationSite, + ArrayList result) { + + ReferenceBinding currentType = receiverType; + ReferenceBinding[] interfacesToVisit = null; + int nextPosition = 0; + do { + ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); + if (itsInterfaces != Binding.NO_SUPERINTERFACES) { + if (interfacesToVisit == null) { + interfacesToVisit = itsInterfaces; + nextPosition = interfacesToVisit.length; + } else { + int itsLength = itsInterfaces.length; + if (nextPosition + itsLength >= interfacesToVisit.length) + System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); + nextInterface : for (int a = 0; a < itsLength; a++) { + ReferenceBinding next = itsInterfaces[a]; + for (int b = 0; b < nextPosition; b++) + if (next == interfacesToVisit[b]) continue nextInterface; + interfacesToVisit[nextPosition++] = next; + } + } + } + + FieldBinding[] fields = currentType.availableFields(); + if(fields != null && fields.length > 0) { + computeAlreadyDefinedName( + fields, + scope, + onlyStaticFields, + receiverType, + invocationSite, + result); + } + currentType = currentType.superclass(); + } while ( currentType != null); + + if (interfacesToVisit != null) { + for (int i = 0; i < nextPosition; i++) { + ReferenceBinding anInterface = interfacesToVisit[i]; + FieldBinding[] fields = anInterface.availableFields(); + if(fields != null) { + computeAlreadyDefinedName( + fields, + scope, + onlyStaticFields, + receiverType, + invocationSite, + result); + } + + ReferenceBinding[] itsInterfaces = anInterface.superInterfaces(); + if (itsInterfaces != Binding.NO_SUPERINTERFACES) { + int itsLength = itsInterfaces.length; + if (nextPosition + itsLength >= interfacesToVisit.length) + System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); + nextInterface : for (int a = 0; a < itsLength; a++) { + ReferenceBinding next = itsInterfaces[a]; + for (int b = 0; b < nextPosition; b++) + if (next == interfacesToVisit[b]) continue nextInterface; + interfacesToVisit[nextPosition++] = next; + } + } + } + } + } + + private void computeAlreadyDefinedName( + FieldBinding[] fields, + Scope scope, + boolean onlyStaticFields, + ReferenceBinding receiverType, + InvocationSite invocationSite, + ArrayList result) { + + next : for (int f = fields.length; --f >= 0;) { + FieldBinding field = fields[f]; + + if (field.isSynthetic()) continue next; + + if (onlyStaticFields && !field.isStatic()) continue next; + + if (!field.canBeSeenBy(receiverType, invocationSite, scope)) continue next; + + result.add(field.name); + } + } + int computeBaseRelevance(){ return R_DEFAULT; }