### 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.194 diff -u -r1.194 CompletionTests.java --- src/org/eclipse/jdt/core/tests/model/CompletionTests.java 4 Feb 2009 16:17:14 -0000 1.194 +++ src/org/eclipse/jdt/core/tests/model/CompletionTests.java 3 Mar 2009 09:42:07 -0000 @@ -19353,4 +19353,71 @@ "", requestor.getResults()); } + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=99399 don't propose final types for extends type completion. +public void testCompletionOnExtendFinalClass () throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/test/Test.java", + "package test;"+ + "class ThisClassIsNotFinal {}" + + "final class ThisClassIsFinal {}" + + "public class Event extends test.ThisClassI {\n" + + "}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + String str = this.workingCopies[0].getSource(); + String completeBehind = "test.ThisClassI"; + int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + + assertResults( + "ThisClassIsNotFinal[TYPE_REF]{ThisClassIsNotFinal, test, Ltest.ThisClassIsNotFinal;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_NON_RESTRICTED + R_CLASS) + "}", + requestor.getResults()); +} + +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=99399 don't propose final types for extends type completion. +public void testCompletionOnExtendFinalClass2() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/test/Test.java", + "package test;"+ + "class ThisClassIsNotFinal {}" + + "final class ThisClassIsFinal {}" + + "public class Event extends ThisClassI {\n" + + "}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + String str = this.workingCopies[0].getSource(); + String completeBehind = "ThisClassI"; + int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + + assertResults( + "ThisClassIsNotFinal[TYPE_REF]{ThisClassIsNotFinal, test, Ltest.ThisClassIsNotFinal;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_UNQUALIFIED + R_NON_RESTRICTED + R_CLASS) + "}", + requestor.getResults()); +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=99399 test to verify that we continue to propose final types +// in other (non extends context). +public void testCompletionOnExtendFinalClass3() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/test/Test.java", + "package test;"+ + "class ThisClassIsNotFinal {}" + + "final class ThisClassIsFinal {}" + + "public class Event extends ThisClassIsFinal {\n" + + " void Boo (ThisClassI x) {}\n" + + "}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + String str = this.workingCopies[0].getSource(); + String completeBehind = "ThisClassI"; + int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + + assertResults( + "ThisClassIsFinal[TYPE_REF]{ThisClassIsFinal, test, Ltest.ThisClassIsFinal;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_UNQUALIFIED + R_NON_RESTRICTED) + "}\n" + + "ThisClassIsNotFinal[TYPE_REF]{ThisClassIsNotFinal, test, Ltest.ThisClassIsNotFinal;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_UNQUALIFIED + R_NON_RESTRICTED) + "}", + requestor.getResults()); +} + } Index: src/org/eclipse/jdt/core/tests/model/CompletionTests_1_5.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests_1_5.java,v retrieving revision 1.111 diff -u -r1.111 CompletionTests_1_5.java --- src/org/eclipse/jdt/core/tests/model/CompletionTests_1_5.java 30 Jan 2009 15:47:20 -0000 1.111 +++ src/org/eclipse/jdt/core/tests/model/CompletionTests_1_5.java 3 Mar 2009 09:42:31 -0000 @@ -13476,4 +13476,105 @@ requestor.getResults()); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=99399 test to verify that we continue to propose final +// types in extends contexts but where they are not directly extended. +public void testCompletionOnExtends() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src3/test/Test.java", + "package test;\n" + + "class X {};\n" + + "final class ThisClassIsFinal {}\n" + + "class ThisClassIsNotFinal {}\n" + + "public class Test extends X {}"); + + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + + String str = this.workingCopies[0].getSource(); + String completeBehind = "ThisClassI"; + int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + + assertResults( + "ThisClassIsFinal[TYPE_REF]{ThisClassIsFinal, test, Ltest.ThisClassIsFinal;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_UNQUALIFIED + R_NON_RESTRICTED + R_CLASS) + "}\n" + + "ThisClassIsNotFinal[TYPE_REF]{ThisClassIsNotFinal, test, Ltest.ThisClassIsNotFinal;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_UNQUALIFIED + R_NON_RESTRICTED + R_CLASS) + "}", + requestor.getResults()); +} + +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=99399 test to verify that we don't propose final +//types in extends contexts where we should not. +public void testCompletionOnExtends2() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src3/test/Test.java", + "package test;\n" + + "final class ThisClassIsFinal {}\n" + + "class ThisClassIsNotFinal {}\n" + + "public class Test {}\n"); + + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + + String str = this.workingCopies[0].getSource(); + String completeBehind = "ThisClassI"; + int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + + assertResults( + "ThisClassIsNotFinal[TYPE_REF]{ThisClassIsNotFinal, test, Ltest.ThisClassIsNotFinal;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_UNQUALIFIED + R_NON_RESTRICTED) + "}", + requestor.getResults()); +} + +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=99399 test to verify that we don't propose final +//types in extends contexts where we should not. +public void testCompletionOnExtends3() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src3/test/Test.java", + "package test;\n" + + "final class ThisClassIsFinal {}\n" + + "class ThisClassIsNotFinal {}\n" + + "public class Test {\n" + + " Test(Bag p) {}" + + "}\n"); + + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + + String str = this.workingCopies[0].getSource(); + String completeBehind = "ThisClassI"; + int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + + assertResults( + "ThisClassIsNotFinal[TYPE_REF]{ThisClassIsNotFinal, test, Ltest.ThisClassIsNotFinal;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_UNQUALIFIED + R_NON_RESTRICTED) + "}", + requestor.getResults()); +} + +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=99399 test to verify that we do propose final +//types in super contexts where we should. +public void testCompletionOnExtends4() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src3/test/Test.java", + "package test;\n" + + "final class ThisClassIsFinal {}\n" + + "class ThisClassIsNotFinal {}\n" + + "public class Test {\n" + + " void boo() {\n" + + " Bag local;\n" + + " }\n" + + "}\n"); + + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + + String str = this.workingCopies[0].getSource(); + String completeBehind = "ThisClassI"; + int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + + assertResults( + "ThisClassIsFinal[TYPE_REF]{ThisClassIsFinal, test, Ltest.ThisClassIsFinal;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_UNQUALIFIED + R_NON_RESTRICTED) + "}\n" + + "ThisClassIsNotFinal[TYPE_REF]{ThisClassIsNotFinal, test, Ltest.ThisClassIsNotFinal;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_UNQUALIFIED + R_NON_RESTRICTED) + "}", + requestor.getResults()); +} + } #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/parser/GenericsCompletionParserTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/GenericsCompletionParserTest.java,v retrieving revision 1.36 diff -u -r1.36 GenericsCompletionParserTest.java --- src/org/eclipse/jdt/core/tests/compiler/parser/GenericsCompletionParserTest.java 27 Jun 2008 16:04:46 -0000 1.36 +++ src/org/eclipse/jdt/core/tests/compiler/parser/GenericsCompletionParserTest.java 3 Mar 2009 09:42:57 -0000 @@ -39,7 +39,7 @@ String completeBehind = "Z."; int cursorLocation = str.indexOf("Z.") + completeBehind.length() - 1; String expectedCompletionNodeToString = ".>"; - String expectedParentNodeToString = ""; + String expectedParentNodeToString = "T extends .>"; String completionIdentifier = ""; String expectedReplacedSource = "Z."; String expectedUnitDisplayString = @@ -67,7 +67,7 @@ String completeBehind = "Z.W"; int cursorLocation = str.indexOf("Z.W") + completeBehind.length() - 1; String expectedCompletionNodeToString = ".W>"; - String expectedParentNodeToString = ""; + String expectedParentNodeToString = "T extends .W>"; String completionIdentifier = "W"; String expectedReplacedSource = "Z.W"; String expectedUnitDisplayString = @@ -95,7 +95,7 @@ String completeBehind = "X.Z"; int cursorLocation = str.indexOf("X.Z") + completeBehind.length() - 1; String expectedCompletionNodeToString = ".Z>"; - String expectedParentNodeToString = ""; + String expectedParentNodeToString = "T extends .Z>"; String completionIdentifier = "Z"; String expectedReplacedSource = "test0001.X.Z"; String expectedUnitDisplayString = @@ -428,7 +428,11 @@ String completeBehind = "Y."; int cursorLocation = str.indexOf("Y.") + completeBehind.length() - 1; String expectedCompletionNodeToString = ".>"; - String expectedParentNodeToString = ""; + String expectedParentNodeToString = + "public class X extends .> {\n" + + " public X() {\n" + + " }\n" + + "}"; String completionIdentifier = ""; String expectedReplacedSource = "Y."; String expectedUnitDisplayString = @@ -623,7 +627,7 @@ String completeBehind = "Y."; int cursorLocation = str.indexOf("Y.") + completeBehind.length() - 1; String expectedCompletionNodeToString = ".>"; - String expectedParentNodeToString = ""; + String expectedParentNodeToString = "T extends .>"; String completionIdentifier = ""; String expectedReplacedSource = "Y."; String expectedUnitDisplayString = @@ -654,7 +658,7 @@ String completeBehind = "Y."; int cursorLocation = str.indexOf("Y.") + completeBehind.length() - 1; String expectedCompletionNodeToString = ".>"; - String expectedParentNodeToString = ""; + String expectedParentNodeToString = "T extends .>"; String completionIdentifier = ""; String expectedReplacedSource = "Y."; String expectedUnitDisplayString = @@ -685,7 +689,7 @@ String completeBehind = "Y."; int cursorLocation = str.indexOf("Y.") + completeBehind.length() - 1; String expectedCompletionNodeToString = ".>"; - String expectedParentNodeToString = ""; + String expectedParentNodeToString = "T extends .>"; String completionIdentifier = ""; String expectedReplacedSource = "Y."; String expectedUnitDisplayString = @@ -715,7 +719,7 @@ String completeBehind = "Y."; int cursorLocation = str.indexOf("Y.") + completeBehind.length() - 1; String expectedCompletionNodeToString = ".>"; - String expectedParentNodeToString = ""; + String expectedParentNodeToString = "T extends .>"; String completionIdentifier = ""; String expectedReplacedSource = "Y."; String expectedUnitDisplayString = @@ -745,7 +749,7 @@ String completeBehind = "Y."; int cursorLocation = str.indexOf("Y.") + completeBehind.length() - 1; String expectedCompletionNodeToString = ".>"; - String expectedParentNodeToString = ""; + String expectedParentNodeToString = "T extends .>"; String completionIdentifier = ""; String expectedReplacedSource = "Y."; String expectedUnitDisplayString = @@ -777,7 +781,7 @@ String completeBehind = "Y."; int cursorLocation = str.indexOf("Y.") + completeBehind.length() - 1; String expectedCompletionNodeToString = ".>"; - String expectedParentNodeToString = ""; + String expectedParentNodeToString = "T extends .>"; String completionIdentifier = ""; String expectedReplacedSource = "Y."; String expectedUnitDisplayString = @@ -809,7 +813,7 @@ String completeBehind = "Y."; int cursorLocation = str.indexOf("Y.") + completeBehind.length() - 1; String expectedCompletionNodeToString = ".>"; - String expectedParentNodeToString = ""; + String expectedParentNodeToString = "T extends .>"; String completionIdentifier = ""; String expectedReplacedSource = "Y."; String expectedUnitDisplayString = @@ -841,7 +845,7 @@ String completeBehind = "Y."; int cursorLocation = str.indexOf("Y.") + completeBehind.length() - 1; String expectedCompletionNodeToString = ".>"; - String expectedParentNodeToString = ""; + String expectedParentNodeToString = "T extends .>"; String completionIdentifier = ""; String expectedReplacedSource = "Y."; String expectedUnitDisplayString = @@ -872,7 +876,7 @@ String completeBehind = "Y."; int cursorLocation = str.indexOf("Y.") + completeBehind.length() - 1; String expectedCompletionNodeToString = ".>"; - String expectedParentNodeToString = ""; + String expectedParentNodeToString = "T extends .>"; String completionIdentifier = ""; String expectedReplacedSource = "Y."; String expectedUnitDisplayString = @@ -902,7 +906,7 @@ String completeBehind = "Y."; int cursorLocation = str.indexOf("Y.") + completeBehind.length() - 1; String expectedCompletionNodeToString = ".>"; - String expectedParentNodeToString = ""; + String expectedParentNodeToString = "T extends .>"; String completionIdentifier = ""; String expectedReplacedSource = "Y."; String expectedUnitDisplayString = @@ -7792,7 +7796,7 @@ String completeBehind = "Z"; int cursorLocation = str.indexOf("Z") + completeBehind.length() - 1; String expectedCompletionNodeToString = ""; - String expectedParentNodeToString = ""; + String expectedParentNodeToString = "T extends "; String completionIdentifier = "Z"; String expectedReplacedSource = "Z"; String expectedUnitDisplayString = @@ -7820,7 +7824,7 @@ String completeBehind = "Z"; int cursorLocation = str.indexOf("Z") + completeBehind.length() - 1; String expectedCompletionNodeToString = ""; - String expectedParentNodeToString = ""; + String expectedParentNodeToString = "T extends "; String completionIdentifier = "Z"; String expectedReplacedSource = "X.Z"; String expectedUnitDisplayString = @@ -7848,7 +7852,7 @@ String completeBehind = "Z"; int cursorLocation = str.indexOf("Z") + completeBehind.length() - 1; String expectedCompletionNodeToString = ".Z>"; - String expectedParentNodeToString = ""; + String expectedParentNodeToString = "T extends .Z>"; String completionIdentifier = "Z"; String expectedReplacedSource = "X.Z"; String expectedUnitDisplayString = @@ -7877,7 +7881,7 @@ String completeBehind = "Z"; int cursorLocation = str.indexOf("Z") + completeBehind.length() - 1; String expectedCompletionNodeToString = ".Z>"; - String expectedParentNodeToString = ""; + String expectedParentNodeToString = "T extends .Z>"; String completionIdentifier = "Z"; String expectedReplacedSource = "X.Z"; String expectedUnitDisplayString = @@ -9057,7 +9061,7 @@ String completeBehind = "Strin"; int cursorLocation = str.indexOf("Strin") + completeBehind.length() - 1; String expectedCompletionNodeToString = ""; - String expectedParentNodeToString = ""; + String expectedParentNodeToString = "? extends "; String completionIdentifier = "Strin"; String expectedReplacedSource = "String"; String expectedUnitDisplayString = @@ -10682,7 +10686,7 @@ String completeBehind = "Obj"; int cursorLocation = str.indexOf("Obj") + completeBehind.length() - 1; String expectedCompletionNodeToString = ""; - String expectedParentNodeToString = ""; + String expectedParentNodeToString = "? extends "; String completionIdentifier = "Obj"; String expectedReplacedSource = "Obj"; String expectedUnitDisplayString = Index: src/org/eclipse/jdt/core/tests/compiler/parser/CompletionParserTest2.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/CompletionParserTest2.java,v retrieving revision 1.49 diff -u -r1.49 CompletionParserTest2.java --- src/org/eclipse/jdt/core/tests/compiler/parser/CompletionParserTest2.java 27 Jun 2008 16:04:46 -0000 1.49 +++ src/org/eclipse/jdt/core/tests/compiler/parser/CompletionParserTest2.java 3 Mar 2009 09:42:47 -0000 @@ -9327,7 +9327,13 @@ String completeBehind = "Z."; int cursorLocation = str.indexOf("Z.") + completeBehind.length() - 1; String expectedCompletionNodeToString = ""; - String expectedParentNodeToString = ""; + String expectedParentNodeToString = + "public class X extends {\n" + + " {\n" + + " }\n" + + " public X() {\n" + + " }\n" + + "}"; String completionIdentifier = ""; String expectedReplacedSource = "Z."; String expectedUnitDisplayString = #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.201 diff -u -r1.201 CompletionParser.java --- codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java 16 Jan 2009 14:29:29 -0000 1.201 +++ codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java 3 Mar 2009 09:43:26 -0000 @@ -2076,6 +2076,11 @@ protected void consumeClassHeaderExtends() { pushOnElementStack(K_NEXT_TYPEREF_IS_CLASS); super.consumeClassHeaderExtends(); + if (this.assistNode != null && this.assistNodeParent == null) { + TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr]; + if (typeDecl != null && typeDecl.superclass == this.assistNode) + this.assistNodeParent = typeDecl; + } popElement(K_NEXT_TYPEREF_IS_CLASS); popElement(K_EXTENDS_KEYWORD); @@ -3752,18 +3757,38 @@ } protected void consumeTypeParameterWithExtends() { super.consumeTypeParameterWithExtends(); + if (this.assistNode != null && this.assistNodeParent == null) { + TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr]; + if (typeParameter != null && typeParameter.type == this.assistNode) + this.assistNodeParent = typeParameter; + } popElement(K_EXTENDS_KEYWORD); } protected void consumeTypeParameterWithExtendsAndBounds() { super.consumeTypeParameterWithExtendsAndBounds(); + if (this.assistNode != null && this.assistNodeParent == null) { + TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr]; + if (typeParameter != null && typeParameter.type == this.assistNode) + this.assistNodeParent = typeParameter; + } popElement(K_EXTENDS_KEYWORD); } protected void consumeTypeParameter1WithExtends() { super.consumeTypeParameter1WithExtends(); + if (this.assistNode != null && this.assistNodeParent == null) { + TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr]; + if (typeParameter != null && typeParameter.type == this.assistNode) + this.assistNodeParent = typeParameter; + } popElement(K_EXTENDS_KEYWORD); } protected void consumeTypeParameter1WithExtendsAndBounds() { super.consumeTypeParameter1WithExtendsAndBounds(); + if (this.assistNode != null && this.assistNodeParent == null) { + TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr]; + if (typeParameter != null && typeParameter.type == this.assistNode) + this.assistNodeParent = typeParameter; + } popElement(K_EXTENDS_KEYWORD); } protected void consumeWildcard() { @@ -3808,18 +3833,38 @@ } protected void consumeWildcardBoundsExtends() { super.consumeWildcardBoundsExtends(); + if (this.assistNode != null && this.assistNodeParent == null) { + Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr]; + if (wildcard != null && wildcard.bound == this.assistNode) + this.assistNodeParent = wildcard; + } popElement(K_EXTENDS_KEYWORD); } protected void consumeWildcardBounds1Extends() { super.consumeWildcardBounds1Extends(); + if (this.assistNode != null && this.assistNodeParent == null) { + Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr]; + if (wildcard != null && wildcard.bound == this.assistNode) + this.assistNodeParent = wildcard; + } popElement(K_EXTENDS_KEYWORD); } protected void consumeWildcardBounds2Extends() { super.consumeWildcardBounds2Extends(); + if (this.assistNode != null && this.assistNodeParent == null) { + Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr]; + if (wildcard != null && wildcard.bound == this.assistNode) + this.assistNodeParent = wildcard; + } popElement(K_EXTENDS_KEYWORD); } protected void consumeWildcardBounds3Extends() { super.consumeWildcardBounds3Extends(); + if (this.assistNode != null && this.assistNodeParent == null) { + Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr]; + if (wildcard != null && wildcard.bound == this.assistNode) + this.assistNodeParent = wildcard; + } popElement(K_EXTENDS_KEYWORD); } protected void consumeUnaryExpression(int op) { 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.388 diff -u -r1.388 CompletionEngine.java --- codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java 5 Feb 2009 09:38:12 -0000 1.388 +++ codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java 3 Mar 2009 09:43:20 -0000 @@ -504,6 +504,7 @@ boolean assistNodeIsAnnotation; boolean assistNodeIsConstructor; boolean assistNodeIsSuperType; + boolean assistNodeIsExtendedType; int assistNodeInJavadoc = 0; boolean assistNodeCanBeSingleMemberAnnotation = false; @@ -1113,6 +1114,7 @@ this.foundTypesCount++; if (this.options.checkDeprecation && (modifiers & ClassFileConstants.AccDeprecated) != 0) return; + if (this.assistNodeIsExtendedType && (modifiers & ClassFileConstants.AccFinal) != 0) return; if (this.options.checkVisibility) { if((modifiers & ClassFileConstants.AccPublic) == 0) { @@ -2761,6 +2763,7 @@ this.assistNodeIsException = ref.isException(); this.assistNodeIsInterface = ref.isInterface(); this.assistNodeIsSuperType = ref.isSuperType(); + this.assistNodeIsExtendedType = assistNodeIsExtendedType(astNode, astNodeParent); this.completionToken = ref.completionIdentifier; long completionPosition = ref.sourcePositions[ref.tokens.length]; @@ -2805,6 +2808,23 @@ } } } + + private boolean assistNodeIsExtendedType(ASTNode astNode, ASTNode astNodeParent) { + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=99399, don't propose final types for extension. + if (astNodeParent == null) + return false; + if (astNodeParent instanceof TypeDeclaration) { + TypeDeclaration typeDeclaration = (TypeDeclaration) astNodeParent; + return (typeDeclaration.superclass == astNode); + } else if (astNodeParent instanceof TypeParameter) { + TypeParameter typeParameter = (TypeParameter) astNodeParent; + return (typeParameter.type == astNode); + } else if (astNodeParent instanceof Wildcard) { + Wildcard wildcard = (Wildcard) astNodeParent; + return (wildcard.bound == astNode && wildcard.kind == Wildcard.EXTENDS); + } + return false; + } private void completionOnQualifiedAllocationExpression(ASTNode astNode, Binding qualifiedBinding, Scope scope) { setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false); @@ -3004,6 +3024,7 @@ this.assistNodeIsInterface = ref.isInterface(); this.assistNodeIsConstructor = ref.isConstructorType; this.assistNodeIsSuperType = ref.isSuperType(); + this.assistNodeIsExtendedType = assistNodeIsExtendedType(astNode, astNodeParent); this.completionToken = ref.completionIdentifier; long completionPosition = ref.sourcePositions[ref.tokens.length]; @@ -3137,6 +3158,7 @@ this.assistNodeIsInterface = singleRef.isInterface(); this.assistNodeIsConstructor = singleRef.isConstructorType; this.assistNodeIsSuperType = singleRef.isSuperType(); + this.assistNodeIsExtendedType = assistNodeIsExtendedType(astNode, astNodeParent); // can be the start of a qualified type name if (qualifiedBinding == null) { @@ -3343,7 +3365,7 @@ this.hasJavaLangObjectAsExpectedType = false; // find types from parent - if(parent instanceof AbstractVariableDeclaration) { + if(parent instanceof AbstractVariableDeclaration && !(parent instanceof TypeParameter)) { AbstractVariableDeclaration variable = (AbstractVariableDeclaration)parent; TypeBinding binding = variable.type.resolvedType; if(binding != null) { @@ -9184,6 +9206,7 @@ typesFound.add(memberType); + if (this.assistNodeIsExtendedType && memberType.isFinal()) continue next; if(!this.insideQualifiedReference) { if(this.assistNodeIsClass) { if(!memberType.isClass()) continue next; @@ -9671,6 +9694,7 @@ continue next; } + if (this.assistNodeIsExtendedType && localType.isFinal()) continue next; if(this.assistNodeIsClass) { if(!localType.isClass()) continue next; } else if(this.assistNodeIsInterface) { @@ -10051,6 +10075,7 @@ typesFound.add(sourceType); + if (this.assistNodeIsExtendedType && sourceType.isFinal()) continue next; if(this.assistNodeIsClass) { if(!sourceType.isClass()) continue next; } else if(this.assistNodeIsInterface) { @@ -10271,6 +10296,7 @@ !scope.isDefinedInSameUnit(sourceType)) continue; + if (this.assistNodeIsExtendedType && sourceType.isFinal()) continue; int accessibility = IAccessRule.K_ACCESSIBLE; if(sourceType.hasRestrictedAccess()) { AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(sourceType); @@ -10463,6 +10489,7 @@ } } + if (this.assistNodeIsExtendedType && refBinding.isFinal()) continue next; if(this.assistNodeIsClass) { if(!refBinding.isClass()) continue next; } else if(this.assistNodeIsInterface) { @@ -10592,6 +10619,7 @@ typesFound.add(typeBinding); + if (this.assistNodeIsExtendedType && typeBinding.isFinal()) continue; if(this.assistNodeIsClass) { if(!typeBinding.isClass()) continue; } else if(this.assistNodeIsInterface) { @@ -10694,6 +10722,7 @@ typesFound.add(typeBinding); + if (this.assistNodeIsExtendedType && typeBinding.isFinal()) continue; if(this.assistNodeIsClass) { if(!typeBinding.isClass()) continue; } else if(this.assistNodeIsInterface) {