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 --- src/org/eclipse/jdt/core/tests/model/CompletionTests.java 19 Oct 2006 14:24:36 -0000 1.132 +++ src/org/eclipse/jdt/core/tests/model/CompletionTests.java 3 Nov 2006 12:48:10 -0000 @@ -10462,6 +10462,32 @@ "foo[VARIABLE_DECLARATION]{foo, null, Ljava.lang.Object;, foo, 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=162743 +public void testCompletionVariableName33() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/test/Test.java", + "package test;\n"+ + "public class Test {\n"+ + " void bar() {\n"+ + " /**/int v\n"+ + " variable = null;\n"+ + " variable = null;\n"+ + " variable = null;\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"+ + "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()); +} public void testCompletionNonEmptyToken1() throws JavaModelException { CompletionTestsRequestor requestor = new CompletionTestsRequestor(); ICompilationUnit cu= getCompilationUnit("Completion", "src", "", "CompletionNonEmptyToken1.java"); Index: codeassist/org/eclipse/jdt/internal/codeassist/UnresolvedReferenceNameFinder.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/UnresolvedReferenceNameFinder.java,v --- codeassist/org/eclipse/jdt/internal/codeassist/UnresolvedReferenceNameFinder.java 23 Oct 2006 16:43:24 -0000 1.2 +++ codeassist/org/eclipse/jdt/internal/codeassist/UnresolvedReferenceNameFinder.java 3 Nov 2006 12:48:12 -0000 @@ -29,7 +29,7 @@ import org.eclipse.jdt.internal.compiler.lookup.ClassScope; import org.eclipse.jdt.internal.compiler.lookup.MethodScope; import org.eclipse.jdt.internal.compiler.lookup.Scope; -import org.eclipse.jdt.internal.compiler.util.SimpleSet; +import org.eclipse.jdt.internal.compiler.util.SimpleSetOfCharArray; public class UnresolvedReferenceNameFinder extends ASTVisitor { private static final int MAX_LINE_COUNT = 100; @@ -50,7 +50,7 @@ private char[][] potentialVariableNames; private int[] potentialVariableNameStarts; - private SimpleSet acceptedNames = new SimpleSet(); + private SimpleSetOfCharArray acceptedNames = new SimpleSetOfCharArray(); public UnresolvedReferenceNameFinder(CompletionEngine completionEngine) { this.parser = completionEngine.parser; Index: compiler/org/eclipse/jdt/internal/compiler/util/SimpleSetOfCharArray.java =================================================================== RCS file: compiler/org/eclipse/jdt/internal/compiler/util/SimpleSetOfCharArray.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ compiler/org/eclipse/jdt/internal/compiler/util/SimpleSetOfCharArray.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,128 @@ +/******************************************************************************* + * Copyright (c) 2006 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.util; + +import org.eclipse.jdt.core.compiler.CharOperation; + +/** + * A simple lookup table is a non-synchronized Hashtable, whose keys + * and values are char[]. It also uses linear probing to resolve collisions + * rather than a linked list of hash table entries. + */ +public final class SimpleSetOfCharArray implements Cloneable { + +// to avoid using Enumerations, walk the individual values skipping nulls +public char[][] values; +public int elementSize; // number of elements in the table +public int threshold; + +public SimpleSetOfCharArray() { + this(13); +} + +public SimpleSetOfCharArray(int size) { + if (size < 3) size = 3; + this.elementSize = 0; + this.threshold = size + 1; // size is the expected number of elements + this.values = new char[2 * size + 1][]; +} + +public Object add(char[] object) { + int length = this.values.length; + int index = (CharOperation.hashCode(object) & 0x7FFFFFFF) % length; + char[] current; + while ((current = this.values[index]) != null) { + if (CharOperation.equals(current, object)) return this.values[index] = object; + if (++index == length) index = 0; + } + this.values[index] = object; + + // assumes the threshold is never equal to the size of the table + if (++this.elementSize > this.threshold) rehash(); + return object; +} + +public void asArray(Object[] copy) { + if (this.elementSize != copy.length) + throw new IllegalArgumentException(); + int index = this.elementSize; + for (int i = 0, l = this.values.length; i < l && index > 0; i++) + if (this.values[i] != null) + copy[--index] = this.values[i]; +} + +public void clear() { + for (int i = this.values.length; --i >= 0;) + this.values[i] = null; + this.elementSize = 0; +} + +public Object clone() throws CloneNotSupportedException { + SimpleSetOfCharArray result = (SimpleSetOfCharArray) super.clone(); + result.elementSize = this.elementSize; + result.threshold = this.threshold; + + int length = this.values.length; + result.values = new char[length][]; + System.arraycopy(this.values, 0, result.values, 0, length); + return result; +} + +public boolean includes(char[] object) { + int length = values.length; + int index = (CharOperation.hashCode(object) & 0x7FFFFFFF) % length; + char[] current; + while ((current = values[index]) != null) { + if (CharOperation.equals(current, object)) return true; + if (++index == length) index = 0; + } + return false; +} + +public char[] remove(char[] object) { + int length = values.length; + int index = (CharOperation.hashCode(object) & 0x7FFFFFFF) % length; + char[] current; + while ((current = values[index]) != null) { + if (CharOperation.equals(current, object)) { + elementSize--; + char[] oldValue = values[index]; + values[index] = null; + if (values[index + 1 == length ? 0 : index + 1] != null) + rehash(); // only needed if a possible collision existed + return oldValue; + } + if (++index == length) index = 0; + } + return null; +} + +private void rehash() { + SimpleSetOfCharArray newSet = new SimpleSetOfCharArray(elementSize * 2); // double the number of expected elements + char[] current; + for (int i = values.length; --i >= 0;) + if ((current = values[i]) != null) + newSet.add(current); + + this.values = newSet.values; + this.elementSize = newSet.elementSize; + this.threshold = newSet.threshold; +} + +public String toString() { + String s = ""; //$NON-NLS-1$ + char[] object; + for (int i = 0, l = values.length; i < l; i++) + if ((object = values[i]) != null) + s += new String(object) + "\n"; //$NON-NLS-1$ + return s; +} +}