diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corext/template/java/CodeSnippetTemplate.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corext/template/java/CodeSnippetTemplate.java index 48c94f6d7b..07377c509c 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corext/template/java/CodeSnippetTemplate.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corext/template/java/CodeSnippetTemplate.java @@ -110,7 +110,7 @@ class TemplatePreferences { public static final String TRYCATCH_CONTENT = "try {\n" + "\t$$TM_SELECTED_TEXT$${1}\n" + "} catch ($${2:Exception} $${3:e}) {\n" + "\t$${0}// TODO: handle exception\n" + "}"; public static final String TRYRESOURCES_CONTENT = "try ($${1}) {\n" + "\t$$TM_SELECTED_TEXT$${2}\n" + "} catch ($${3:Exception} $${4:e}) {\n" + "\t$${0}// TODO: handle exception\n" + "}"; public static final String MAIN_CONTENT = "public static void main(String[] args) {\n" + "\t$${0}\n" + "}"; - public static final String CTOR_CONTENT = "$${1|public,protected,private|} $${2:$$TM_FILENAME_BASE}($${3}) {\n" + "\t$${4:super();}$${0}\n" + "}"; + public static final String CTOR_CONTENT = "$${1|public,protected,private|} ${enclosing_simple_type}($${2}) {\n" + "\t$${3:super();}$${0}\n" + "}"; public static final String METHOD_CONTENT = "$${1|public,protected,private|}$${2| , static |}$${3:void} $${4:name}($${5}) {\n" + "\t$${0}\n" + "}"; public static final String NEW_CONTENT = "$${1:Object} $${2:foo} = new $${1}($${3});\n" + "$${0}"; public static final String FIELD_CONTENT = "$${1|public,protected,private|} $${2:String} $${3:name};"; diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corext/template/java/JavaContextType.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corext/template/java/JavaContextType.java index 3fee9acf04..cde0cccc06 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corext/template/java/JavaContextType.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corext/template/java/JavaContextType.java @@ -13,9 +13,15 @@ package org.eclipse.jdt.ls.core.internal.corext.template.java; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.internal.core.manipulation.JavaElementLabelsCore; import org.eclipse.jdt.internal.corext.template.java.AbstractJavaContextTypeCore; +import org.eclipse.jdt.internal.corext.template.java.CompilationUnitContext; import org.eclipse.jdt.internal.corext.template.java.IJavaContext; +import org.eclipse.jdt.internal.corext.template.java.JavaTemplateMessages; import org.eclipse.jdt.internal.corext.template.java.VarResolver; +import org.eclipse.jface.text.templates.TemplateContext; import org.eclipse.jface.text.templates.TemplateVariableResolver; /** @@ -75,10 +81,44 @@ public void initializeContextTypeResolvers() { // TODO: Some of the resolvers are defined in org.eclipse.jdt.ui/plugin.xml, now we have to add them manually. // See: https://github.com/eclipse-jdt/eclipse.jdt.ui/blob/dc995e7a0069e1eca58b19a4bc365032c50b0201/org.eclipse.jdt.ui/plugin.xml#L5674-L5752 addResolver("var", new VarResolver()); + addResolver(new SimpleType()); } public synchronized void addResolver(String type, TemplateVariableResolver resolver) { resolver.setType(type); addResolver(resolver); } + + // Copied from org.eclipse.jdt.internal.corext.template.java.CompilationUnitContextType.EnclosingJavaElement + protected static class EnclosingJavaElement extends TemplateVariableResolver { + protected final int fElementType; + + public EnclosingJavaElement(String name, String description, int elementType) { + super(name, description); + fElementType = elementType; + } + + @Override + protected String resolve(TemplateContext context) { + IJavaElement element = ((CompilationUnitContext) context).findEnclosingElement(fElementType); + if (element instanceof IType) { + // Flag was changed to permit non-qualified types + return JavaElementLabelsCore.getElementLabel(element, 0); + } + return (element == null) ? null : element.getElementName(); + } + + @Override + protected boolean isUnambiguous(TemplateContext context) { + return resolve(context) != null; + } + } + + // Copied from org.eclipse.jdt.internal.corext.template.java.CompilationUnitContextType.Type + protected static class SimpleType extends EnclosingJavaElement { + public SimpleType() { + super("enclosing_simple_type", JavaTemplateMessages.CompilationUnitContextType_variable_description_enclosing_type, IJavaElement.TYPE); + } + } } + diff --git a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/CompletionHandlerTest.java b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/CompletionHandlerTest.java index 310f703a8a..4c01b20432 100644 --- a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/CompletionHandlerTest.java +++ b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/CompletionHandlerTest.java @@ -1282,6 +1282,28 @@ public void testSnippet_multiline_string() throws JavaModelException { assertTrue(items.size() > 0); } + @Test + public void testSnippet_ctor() throws JavaModelException { + //@formatter:off + ICompilationUnit unit = getWorkingCopy( + "src/org/sample/Test.java", + "package org.sample;\n" + + "public class MainClass {\n" + + "}" + + "class AnotherClass {\n" + + "ctor\n" + + "}" + ); + //@formatter:on + CompletionList list = requestCompletions(unit, "ctor"); + assertNotNull(list); + List items = new ArrayList<>(list.getItems()); + CompletionItem item = items.get(0); + assertEquals("ctor", item.getLabel()); + String newText = item.getTextEdit().getLeft().getNewText(); + assertEquals("${1|public,protected,private|} AnotherClass(${2}) {\n" + "\t${3:super();}${0}\n" + "}", newText); + } + @Test public void testSnippet_interface() throws JavaModelException { ICompilationUnit unit = getWorkingCopy("src/org/sample/Test.java", "");