### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.text.tests diff --git src/org/eclipse/jdt/text/tests/contentassist/CodeCompletionTest.java src/org/eclipse/jdt/text/tests/contentassist/CodeCompletionTest.java index 72fd010..85ea378 100644 --- src/org/eclipse/jdt/text/tests/contentassist/CodeCompletionTest.java +++ src/org/eclipse/jdt/text/tests/contentassist/CodeCompletionTest.java @@ -199,6 +199,7 @@ CompletionProposalCollector collector= createCollector(cu, offset); collector.setReplacementLength(0); + collector.setAllowsRequiredProposals(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF, true); codeComplete(cu, offset, collector); @@ -489,6 +490,612 @@ assertEquals(buf.toString(), doc.get()); } + public void testAnonymousTypeCompletion7() throws Exception { + // bug 333428#c0 => button.addSelectionListener(new SelectionL + IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class A {\n"); + buf.append(" public void foo(Runnable r) {\n"); + buf.append(" }\n"); + buf.append(" public void bar() {\n"); + buf.append(" foo(new Runn\n"); + buf.append(" }\n"); + buf.append("}\n"); + String contents= buf.toString(); + + ICompilationUnit cu= pack1.createCompilationUnit("A.java", contents, false, null); + + String str= "foo(new Runn"; + + int offset= contents.indexOf(str) + str.length(); + + CompletionProposalCollector collector= createCollector(cu, offset); + collector.setReplacementLength(0); + collector.setAllowsRequiredProposals(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF, true); + + codeComplete(cu, offset, collector); + + IJavaCompletionProposal[] proposals= collector.getJavaCompletionProposals(); + + assertNumberOf("proposals", proposals.length, 1); + + IDocument doc= new Document(contents); + + proposals[0].apply(doc); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class A {\n"); + buf.append(" public void foo(Runnable r) {\n"); + buf.append(" }\n"); + buf.append(" public void bar() {\n"); + buf.append(" foo(new Runnable() {\n"); + buf.append(" \n"); + buf.append(" public void run() {\n"); + buf.append(" //TODO\n"); + buf.append(" \n"); + buf.append(" }\n"); + buf.append(" });\n"); + buf.append(" }\n"); + buf.append("}\n"); + assertEquals(buf.toString(), doc.get()); + } + + public void testAnonymousTypeCompletion8() throws Exception { + // bug 333428#c0 => button.addSelectionListener(new SelectionL) + IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class A {\n"); + buf.append(" public void foo(Runnable r) {\n"); + buf.append(" }\n"); + buf.append(" public void bar() {\n"); + buf.append(" foo(new Runn)\n"); + buf.append(" }\n"); + buf.append("}\n"); + String contents= buf.toString(); + + ICompilationUnit cu= pack1.createCompilationUnit("A.java", contents, false, null); + + String str= "foo(new Runn"; + + int offset= contents.indexOf(str) + str.length(); + + CompletionProposalCollector collector= createCollector(cu, offset); + collector.setReplacementLength(0); + collector.setAllowsRequiredProposals(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF, true); + + codeComplete(cu, offset, collector); + + IJavaCompletionProposal[] proposals= collector.getJavaCompletionProposals(); + + assertNumberOf("proposals", proposals.length, 1); + + IDocument doc= new Document(contents); + + proposals[0].apply(doc); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class A {\n"); + buf.append(" public void foo(Runnable r) {\n"); + buf.append(" }\n"); + buf.append(" public void bar() {\n"); + buf.append(" foo(new Runnable() {\n"); + buf.append(" \n"); + buf.append(" public void run() {\n"); + buf.append(" //TODO\n"); + buf.append(" \n"); + buf.append(" }\n"); + buf.append(" });\n"); + buf.append(" }\n"); + buf.append("}\n"); + assertEquals(buf.toString(), doc.get()); + } + + + public void testAnonymousTypeCompletion9() throws Exception { + // bug 333428#c0 => button.addSelectionListener(new SelectionL); + IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class A {\n"); + buf.append(" public void foo(Runnable r) {\n"); + buf.append(" }\n"); + buf.append(" public void bar() {\n"); + buf.append(" foo(new Runn);\n"); + buf.append(" }\n"); + buf.append("}\n"); + String contents= buf.toString(); + + ICompilationUnit cu= pack1.createCompilationUnit("A.java", contents, false, null); + + String str= "foo(new Runn"; + + int offset= contents.indexOf(str) + str.length(); + + CompletionProposalCollector collector= createCollector(cu, offset); + collector.setReplacementLength(0); + collector.setAllowsRequiredProposals(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF, true); + + codeComplete(cu, offset, collector); + + IJavaCompletionProposal[] proposals= collector.getJavaCompletionProposals(); + + assertNumberOf("proposals", proposals.length, 1); + + IDocument doc= new Document(contents); + + proposals[0].apply(doc); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class A {\n"); + buf.append(" public void foo(Runnable r) {\n"); + buf.append(" }\n"); + buf.append(" public void bar() {\n"); + buf.append(" foo(new Runnable() {\n"); + buf.append(" \n"); + buf.append(" public void run() {\n"); + buf.append(" //TODO\n"); + buf.append(" \n"); + buf.append(" }\n"); + buf.append(" });\n"); + buf.append(" }\n"); + buf.append("}\n"); + assertEquals(buf.toString(), doc.get()); + } + + public void testAnonymousTypeCompletion10() throws Exception { + IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class A {\n"); + buf.append(" private Runnable jobs[] = {\n"); + buf.append(" new Runn\n"); + buf.append(" };\n"); + buf.append("}\n"); + String contents= buf.toString(); + + ICompilationUnit cu= pack1.createCompilationUnit("A.java", contents, false, null); + + String str= "new Runn"; + + int offset= contents.indexOf(str) + str.length(); + + CompletionProposalCollector collector= createCollector(cu, offset); + collector.setReplacementLength(0); + collector.setAllowsRequiredProposals(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF, true); + + codeComplete(cu, offset, collector); + + IJavaCompletionProposal[] proposals= collector.getJavaCompletionProposals(); + + assertNumberOf("proposals", proposals.length, 1); + + IDocument doc= new Document(contents); + + proposals[0].apply(doc); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class A {\n"); + buf.append(" private Runnable jobs[] = {\n"); + buf.append(" new Runnable() {\n"); + buf.append(" \n"); + buf.append(" public void run() {\n"); + buf.append(" //TODO\n"); + buf.append(" \n"); + buf.append(" }\n"); + buf.append(" }\n"); + buf.append(" };\n"); + buf.append("}\n"); + assertEquals(buf.toString(), doc.get()); + } + + + + public void testAnonymousTypeCompletion11() throws Exception { + IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class A {\n"); + buf.append(" private Runnable jobs[] = {new Runn}\n"); + buf.append("}\n"); + String contents= buf.toString(); + + ICompilationUnit cu= pack1.createCompilationUnit("A.java", contents, false, null); + + String str= "new Runn"; + + int offset= contents.indexOf(str) + str.length(); + + CompletionProposalCollector collector= createCollector(cu, offset); + collector.setReplacementLength(0); + collector.setAllowsRequiredProposals(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF, true); + + codeComplete(cu, offset, collector); + + IJavaCompletionProposal[] proposals= collector.getJavaCompletionProposals(); + + assertNumberOf("proposals", proposals.length, 1); + + IDocument doc= new Document(contents); + + proposals[0].apply(doc); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class A {\n"); + buf.append(" private Runnable jobs[] = {new Runnable() {\n"); + buf.append(" \n"); + buf.append(" public void run() {\n"); + buf.append(" //TODO\n"); + buf.append(" \n"); + buf.append(" }\n"); + buf.append(" }};\n"); + buf.append("}\n"); + assertEquals(buf.toString(), doc.get()); + } + + public void testAnonymousTypeCompletion12() throws Exception { + IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class A {\n"); + buf.append(" public void foo(Runnable r) {\n"); + buf.append(" }\n"); + buf.append(" public void bar() {\n"); + buf.append(" foo(new Runn)\n"); + buf.append(" System.out.println();\n"); + buf.append(" }\n"); + buf.append("}\n"); + String contents= buf.toString(); + + ICompilationUnit cu= pack1.createCompilationUnit("A.java", contents, false, null); + + String str= "foo(new Runn"; + + int offset= contents.indexOf(str) + str.length(); + + CompletionProposalCollector collector= createCollector(cu, offset); + collector.setReplacementLength(0); + collector.setAllowsRequiredProposals(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF, true); + + codeComplete(cu, offset, collector); + + IJavaCompletionProposal[] proposals= collector.getJavaCompletionProposals(); + + assertNumberOf("proposals", proposals.length, 1); + + IDocument doc= new Document(contents); + + proposals[0].apply(doc); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class A {\n"); + buf.append(" public void foo(Runnable r) {\n"); + buf.append(" }\n"); + buf.append(" public void bar() {\n"); + buf.append(" foo(new Runnable() {\n"); + buf.append(" \n"); + buf.append(" public void run() {\n"); + buf.append(" //TODO\n"); + buf.append(" \n"); + buf.append(" }\n"); + buf.append(" });\n"); + buf.append(" System.out.println();\n"); + buf.append(" }\n"); + buf.append("}\n"); + assertEquals(buf.toString(), doc.get()); + } + + public void testAnonymousTypeCompletion13() throws Exception { + IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class A {\n"); + buf.append(" private void foo() {\n"); + buf.append(" bar(new Runnable());\n"); + buf.append(" }\n"); + buf.append(" void bar(Runnable rs) {}\n"); + buf.append("}\n"); + String contents= buf.toString(); + + ICompilationUnit cu= pack1.createCompilationUnit("A.java", contents, false, null); + + String str= "bar(new Runnable("; + + int offset= contents.indexOf(str) + str.length(); + System.out.println(contents.charAt(offset)); + + CompletionProposalCollector collector= createCollector(cu, offset); + collector.setReplacementLength(0); + collector.setAllowsRequiredProposals(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF, true); + + codeComplete(cu, offset, collector); + + IJavaCompletionProposal[] proposals= collector.getJavaCompletionProposals(); + + assertNumberOf("proposals", proposals.length, 1); + + IDocument doc= new Document(contents); + + proposals[0].apply(doc); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class A {\n"); + buf.append(" private void foo() {\n"); + buf.append(" bar(new Runnable() {\n"); + buf.append(" \n"); + buf.append(" public void run() {\n"); + buf.append(" //TODO\n"); + buf.append(" \n"); + buf.append(" }\n"); + buf.append(" });\n"); + buf.append(" }\n"); + buf.append(" void bar(Runnable rs) {}\n"); + buf.append("}\n"); + assertEquals(buf.toString(), doc.get()); + } + + public void testAnonymousTypeCompletion14() throws Exception { + IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class A {\n"); + buf.append(" private void foo() {\n"); + buf.append(" bar(new Runnable[] {\n"); + buf.append(" new Runnable(\n"); + buf.append(" });\n"); + buf.append(" }\n"); + buf.append("\n"); + buf.append(" void bar(Runnable[] rs) {\n"); + buf.append(" }\n"); + buf.append("}\n"); + String contents= buf.toString(); + + ICompilationUnit cu= pack1.createCompilationUnit("A.java", contents, false, null); + + String str= " new Runnable("; + + int offset= contents.indexOf(str) + str.length(); + System.out.println(contents.charAt(offset)); + + CompletionProposalCollector collector= createCollector(cu, offset); + collector.setReplacementLength(0); + collector.setAllowsRequiredProposals(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF, true); + + codeComplete(cu, offset, collector); + + IJavaCompletionProposal[] proposals= collector.getJavaCompletionProposals(); + + assertNumberOf("proposals", proposals.length, 1); + + IDocument doc= new Document(contents); + + proposals[0].apply(doc); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class A {\n"); + buf.append(" private void foo() {\n"); + buf.append(" bar(new Runnable[] {\n"); + buf.append(" new Runnable() {\n"); + buf.append(" \n"); + buf.append(" public void run() {\n"); + buf.append(" //TODO\n"); + buf.append(" \n"); + buf.append(" }\n"); + buf.append(" }\n"); + buf.append(" });\n"); + buf.append(" }\n"); + buf.append("\n"); + buf.append(" void bar(Runnable[] rs) {\n"); + buf.append(" }\n"); + buf.append("}\n"); + assertEquals(buf.toString(), doc.get()); + } + + public void testAnonymousTypeCompletion15() throws Exception { + IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("\n"); + buf.append("public class A {\n"); + buf.append(" public void foo(Runnable r) {\n"); + buf.append(" }\n"); + buf.append("\n"); + buf.append(" public void bar() {\n"); + buf.append(" foo(new Runna\n"); + buf.append(" );\n"); + buf.append(" }\n"); + buf.append("}\n"); + String contents= buf.toString(); + + ICompilationUnit cu= pack1.createCompilationUnit("A.java", contents, false, null); + + String str= "foo(new Runna"; + + int offset= contents.indexOf(str) + str.length(); + System.out.println(contents.charAt(offset)); + + CompletionProposalCollector collector= createCollector(cu, offset); + collector.setReplacementLength(0); + collector.setAllowsRequiredProposals(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF, true); + + codeComplete(cu, offset, collector); + + IJavaCompletionProposal[] proposals= collector.getJavaCompletionProposals(); + + assertNumberOf("proposals", proposals.length, 1); + + IDocument doc= new Document(contents); + + proposals[0].apply(doc); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("\n"); + buf.append("public class A {\n"); + buf.append(" public void foo(Runnable r) {\n"); + buf.append(" }\n"); + buf.append("\n"); + buf.append(" public void bar() {\n"); + buf.append(" foo(new Runnable() {\n"); + buf.append(" \n"); + buf.append(" public void run() {\n"); + buf.append(" //TODO\n"); + buf.append(" \n"); + buf.append(" }\n"); + buf.append(" }\n"); + buf.append(" );\n"); + buf.append(" }\n"); + buf.append("}\n"); + assertEquals(buf.toString(), doc.get()); + } + + public void testAnonymousTypeCompletion16() throws Exception { + IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("\n"); + buf.append("public class A {\n"); + buf.append(" public void foo(Runnable r) {\n"); + buf.append(" }\n"); + buf.append("\n"); + buf.append(" public void bar() {\n"); + buf.append(" foo(new Runna\n"); + buf.append(" )\n"); + buf.append(" }\n"); + buf.append("}\n"); + String contents= buf.toString(); + + ICompilationUnit cu= pack1.createCompilationUnit("A.java", contents, false, null); + + String str= "foo(new Runna"; + + int offset= contents.indexOf(str) + str.length(); + System.out.println(contents.charAt(offset)); + + CompletionProposalCollector collector= createCollector(cu, offset); + collector.setReplacementLength(0); + collector.setAllowsRequiredProposals(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF, true); + + codeComplete(cu, offset, collector); + + IJavaCompletionProposal[] proposals= collector.getJavaCompletionProposals(); + + assertNumberOf("proposals", proposals.length, 1); + + IDocument doc= new Document(contents); + + proposals[0].apply(doc); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("\n"); + buf.append("public class A {\n"); + buf.append(" public void foo(Runnable r) {\n"); + buf.append(" }\n"); + buf.append("\n"); + buf.append(" public void bar() {\n"); + buf.append(" foo(new Runnable() {\n"); + buf.append(" \n"); + buf.append(" public void run() {\n"); + buf.append(" //TODO\n"); + buf.append(" \n"); + buf.append(" }\n"); + buf.append(" }\n"); + buf.append(" );\n"); + buf.append(" }\n"); + buf.append("}\n"); + assertEquals(buf.toString(), doc.get()); + } + + public void testAnonymousTypeCompletion17() throws Exception { + IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("\n"); + buf.append("public class A {\n"); + buf.append(" public void foo(Runnable r) {\n"); + buf.append(" }\n"); + buf.append("\n"); + buf.append(" public void bar() {\n"); + buf.append(" foo(new Runna\n"); + buf.append(" ;\n"); + buf.append(" }\n"); + buf.append("}\n"); + String contents= buf.toString(); + + ICompilationUnit cu= pack1.createCompilationUnit("A.java", contents, false, null); + + String str= "foo(new Runna"; + + int offset= contents.indexOf(str) + str.length(); + System.out.println(contents.charAt(offset)); + + CompletionProposalCollector collector= createCollector(cu, offset); + collector.setReplacementLength(0); + collector.setAllowsRequiredProposals(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF, true); + + codeComplete(cu, offset, collector); + + IJavaCompletionProposal[] proposals= collector.getJavaCompletionProposals(); + + assertNumberOf("proposals", proposals.length, 1); + + IDocument doc= new Document(contents); + + proposals[0].apply(doc); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("\n"); + buf.append("public class A {\n"); + buf.append(" public void foo(Runnable r) {\n"); + buf.append(" }\n"); + buf.append("\n"); + buf.append(" public void bar() {\n"); + buf.append(" foo(new Runnable() {\n"); + buf.append(" \n"); + buf.append(" public void run() {\n"); + buf.append(" //TODO\n"); + buf.append(" \n"); + buf.append(" }\n"); + buf.append(" })\n"); + buf.append(" ;\n"); + buf.append(" }\n"); + buf.append("}\n"); + assertEquals(buf.toString(), doc.get()); + } + public void testAnonymousTypeCompletionBug280801() throws Exception { IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); @@ -627,7 +1234,7 @@ buf.append(" //TODO\n"); buf.append(" \n"); buf.append(" }\n"); - buf.append(" })\n"); + buf.append(" });\n"); buf.append(" }\n"); buf.append("}\n"); assertEquals("", buf.toString(), doc.get()); #P org.eclipse.jdt.ui diff --git ui/org/eclipse/jdt/internal/ui/text/java/AnonymousTypeCompletionProposal.java ui/org/eclipse/jdt/internal/ui/text/java/AnonymousTypeCompletionProposal.java index 6be59bd..0b7c549 100644 --- ui/org/eclipse/jdt/internal/ui/text/java/AnonymousTypeCompletionProposal.java +++ ui/org/eclipse/jdt/internal/ui/text/java/AnonymousTypeCompletionProposal.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2014 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,6 +71,8 @@ import org.eclipse.jdt.internal.ui.dialogs.OverrideMethodDialog; import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider; import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings; +import org.eclipse.jdt.internal.ui.text.JavaHeuristicScanner; +import org.eclipse.jdt.internal.ui.text.Symbols; public class AnonymousTypeCompletionProposal extends JavaTypeCompletionProposal implements ICompletionProposalExtension4 { @@ -82,7 +84,9 @@ private int fContextInformationPosition; private ImportRewrite fImportRewrite; - + + private final String SEMICOLON= ";"; //$NON-NLS-1$ + private final String ESCAPE_CHAR= "\r"; //$NON-NLS-1$ public AnonymousTypeCompletionProposal(IJavaProject jproject, ICompilationUnit cu, JavaContentAssistInvocationContext invocationContext, int start, int length, String constructorCompletion, StyledString displayName, String declarationSignature, IType superType, int relevance) { super(constructorCompletion, cu, start, length, null, displayName, relevance, null, invocationContext); @@ -371,7 +375,7 @@ if (newBody == null) return false; - CompletionProposal coreProposal= ((MemberProposalInfo)getProposalInfo()).fProposal; + CompletionProposal coreProposal= ((MemberProposalInfo) getProposalInfo()).fProposal; boolean isAnonymousConstructorInvoc= coreProposal.getKind() == CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION; boolean replacementStringEndsWithParentheses= isAnonymousConstructorInvoc || getReplacementString().endsWith(")"); //$NON-NLS-1$ @@ -392,21 +396,31 @@ options.put(DefaultCodeFormatterConstants.FORMATTER_INDENT_EMPTY_LINES, DefaultCodeFormatterConstants.TRUE); String replacementString= CodeFormatterUtil.format(CodeFormatter.K_EXPRESSION, buf.toString(), 0, lineDelim, options); - int lineEndOffset= lineInfo.getOffset() + lineInfo.getLength(); + JavaHeuristicScanner scanner= new JavaHeuristicScanner(document); + IRegion region= scanner.findSurroundingBlock(lineInfo.getOffset()); + int surroundingBlockBound= region.getOffset() + region.getLength(); int p= offset; char ch= document.getChar(p); - while (p < lineEndOffset) { + while (p < surroundingBlockBound) { if (ch == '(' || ch == ')' || ch == ';' || ch == ',') break; ch= document.getChar(++p); } - if (ch != ';' && ch != ',' && ch != ')') + String closingString= getMatchingClosingSymbols(document, offset, lineInfo.getOffset(), lineInfo.getLength()); + if (closingString.length() != 0 && !ESCAPE_CHAR.equals(closingString)) { + if (ch != ';' && ch != ',' && ch != ')') { + replacementString= replacementString + closingString + ';'; + } else { + replacementString= replacementString + closingString; + } + } + if (closingString.length() == 0 && ch != ';' && ch != ',' && ch != ')' && ch != '}') replacementString= replacementString + ';'; replacementString= Strings.changeIndent(replacementString, 0, project, CodeFormatterUtil.createIndentString(indent, project), lineDelim); - + int beginIndex= replacementString.indexOf('('); if (!isAnonymousConstructorInvoc) beginIndex++; @@ -417,18 +431,12 @@ // Keep existing code int endPos= pos; ch= document.getChar(endPos); + int lineEndOffset= lineInfo.getOffset() + lineInfo.getLength(); while (endPos < lineEndOffset && ch != '(' && ch != ')' && ch != ';' && ch != ',' && !Character.isWhitespace(ch)) ch= document.getChar(++endPos); - int keepLength= endPos - pos; - if (keepLength > 0) { - String keepStr= document.get(pos, keepLength); - replacementString= replacementString + keepStr; - setCursorPosition(replacementString.length() - keepLength); - } - } else - setCursorPosition(replacementString.length()); - + } + setCursorPosition(replacementString.length()); setReplacementString(replacementString); if (pos < document.getLength() && document.getChar(pos) == ')') { @@ -441,6 +449,77 @@ return false; } + private String getMatchingClosingSymbols(IDocument doc, int currentOffset, int lineOffset, int bound) throws BadLocationException { + String lineUnderModification= doc.get(lineOffset, bound); + char[] charArray= lineUnderModification.toCharArray(); + String returnChar= ""; //$NON-NLS-1$ + JavaHeuristicScanner scanner= new JavaHeuristicScanner(doc); + IRegion region= scanner.findSurroundingBlock(lineOffset); + int surroundingBlockBound= region.getOffset() + region.getLength(); + + for (int i= 0; i < charArray.length; i++) { + char c= charArray[i]; + if (c == '(' || c == '{') { + char closingChar= getClosingChar(c); + if (c == '(' && lineOffset + i + 1 == currentOffset) + continue; + int scanForward= scanner.findClosingPeer(lineOffset + i + 1, surroundingBlockBound, c, closingChar); + if (scanForward == -1) { + returnChar= closingChar + returnChar; + } + } + } + + int nextToken1= scanner.nextToken(currentOffset, surroundingBlockBound); + if (nextToken1 != -1) { + int position= scanner.getPosition(); + // make sure we do not set the bound more than the document length + if (surroundingBlockBound + 1 < doc.getLength()) + surroundingBlockBound++; + int nextToken2= scanner.nextToken(position, surroundingBlockBound); + if (nextToken2 != -1) { + // e.g. foo(new Run|, null) or new Run|; or Runnable run= new Runnable(|); or Runnable jobs[] = {new Run|}; + if (Symbols.TokenCOMMA == nextToken1 || Symbols.TokenSEMICOLON == nextToken1 || + ((Symbols.TokenRBRACE == nextToken1 || Symbols.TokenRPAREN == nextToken1) && Symbols.TokenSEMICOLON == nextToken2) || + (Symbols.TokenRBRACE == nextToken1 && Symbols.TokenRPAREN == nextToken2)) { + // No need to append semicolon as the code already has a ';' or ',' + return returnChar.length() != 0 ? returnChar : ESCAPE_CHAR; + } + + if (Symbols.TokenRBRACE == nextToken1 && Symbols.TokenRPAREN == nextToken2) { + return ESCAPE_CHAR; + } + + // e.g. Runnable jobs[] = {new Runn} + // We have to append semicolon, but not as part of the replacement string. + if (Symbols.TokenRBRACE == nextToken1) { + doc.replace(position, 0, SEMICOLON); + return ESCAPE_CHAR; + } + } + + // We have to append semicolon, but not as part of the replacement string. + if (Symbols.TokenRPAREN == nextToken1 && !lineUnderModification.trim().endsWith(SEMICOLON)) { + doc.replace(position, 0, SEMICOLON); + return ESCAPE_CHAR; + } + } + return returnChar; + } + + private char getClosingChar(char c) { + switch (c) { + case '(': + return ')'; + + case '{': + return '}'; + + default: + return '\0'; + } + } + /* * @see ICompletionProposalExtension#getContextInformationPosition() * @since 3.4