This is an automated email from the ASF dual-hosted git repository. dbalek pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/master by this push: new 907112b LSP: Various Surround With refactoring fixes. (#3169) 907112b is described below commit 907112b6c5966002d6462967c9a81a916886010e Author: Dusan Balek <dusan.ba...@oracle.com> AuthorDate: Fri Sep 17 09:59:53 2021 +0200 LSP: Various Surround With refactoring fixes. (#3169) --- .../CodeTemplateCompletionProvider.java | 16 ++++++--- .../java/editor/resources/Bundle.properties | 4 +++ .../java/editor/resources/DefaultAbbrevs.xml | 34 +++++++++++++++--- .../java/lsp/server/protocol/SurroundWithHint.java | 41 +++++++++++++++++----- java/java.lsp.server/vscode/src/extension.ts | 17 +++++++++ 5 files changed, 94 insertions(+), 18 deletions(-) diff --git a/ide/editor.codetemplates/src/org/netbeans/lib/editor/codetemplates/CodeTemplateCompletionProvider.java b/ide/editor.codetemplates/src/org/netbeans/lib/editor/codetemplates/CodeTemplateCompletionProvider.java index e0ec7e9..5a56179 100644 --- a/ide/editor.codetemplates/src/org/netbeans/lib/editor/codetemplates/CodeTemplateCompletionProvider.java +++ b/ide/editor.codetemplates/src/org/netbeans/lib/editor/codetemplates/CodeTemplateCompletionProvider.java @@ -89,8 +89,9 @@ public final class CodeTemplateCompletionProvider implements CompletionProvider public static class Collector implements CompletionCollector { private static final String SELECTED_TEXT_VAR = "${0:$TM_SELECTED_TEXT}"; - private static final Pattern SNIPPET_VAR_PATTERN = Pattern.compile("\\$\\{\\s*([-\\w]++)([^}]*)?}"); - private static final Pattern SNIPPET_HINT_PATTERN = Pattern.compile("([-\\w]++)(?:\\s*=\\s*(\\\"([^\\\"]*)\\\"|\\S*))?"); + private static final Pattern SNIPPET_VAR_PATTERN = Pattern.compile("\\$\\{\\s*([-\\w]++)((?:\\s*[-\\w]++(?:\\s*=\\s*(?:\\\"[^\\\"]*\\\"|[-\\w]++))?)*\\s*)?}"); + private static final Pattern SNIPPET_HINT_PATTERN = Pattern.compile("([-\\w]++)(?:\\s*=\\s*(\\\"([^\\\"]*)\\\"|[-\\w]++))?"); + private static final String UNCAUGHT_EXCEPTION_CATCH_STATEMENTS = "uncaughtExceptionCatchStatements"; @Override public boolean collectCompletions(Document doc, int offset, Completion.Context context, Consumer<Completion> consumer) { @@ -100,8 +101,9 @@ public final class CodeTemplateCompletionProvider implements CompletionProvider description = CodeTemplateApiPackageAccessor.get().getSingleLineText(ct); } String label = html2text(description.trim()); + String sortText = String.format("%04d%s", 1650, "fore".equals(ct.getAbbreviation()) ? label.substring(0, 3) : label); consumer.accept(CompletionCollector.newBuilder(label) - .sortText(String.format("%04d%s", 1650, label)) + .sortText(sortText) .documentation(() -> { StringBuffer sb = new StringBuffer("<html><pre>"); ParametrizedTextParser.parseToHtml(sb, ct.getParametrizedText()); @@ -148,7 +150,9 @@ public final class CodeTemplateCompletionProvider implements CompletionProvider if (defaultValue != null) { values.put(name, defaultValue); } - if ("false".equalsIgnoreCase(hints.get(CodeTemplateParameter.EDITABLE_HINT_NAME))) { + if (hints.containsKey(UNCAUGHT_EXCEPTION_CATCH_STATEMENTS)) { + sb.append("catch (${").append(last.incrementAndGet()).append(":Exception} ${").append(last.incrementAndGet()).append(":e}) {\n}"); + } else if ("false".equalsIgnoreCase(hints.get(CodeTemplateParameter.EDITABLE_HINT_NAME))) { nonEditables.add(name); sb.append(values.getOrDefault(name, "")); } else { @@ -171,7 +175,9 @@ public final class CodeTemplateCompletionProvider implements CompletionProvider Matcher matcher = SNIPPET_HINT_PATTERN.matcher(text); int idx = 0; while (matcher.find(idx)) { - hint2Values.put(matcher.group(1), matcher.groupCount() > 2 ? matcher.group(3) : matcher.groupCount() > 1 ? matcher.group(2) : null); + String insideString = matcher.groupCount() > 2 ? matcher.group(3) : null; + String value = matcher.groupCount() > 1 ? matcher.group(2) : null; + hint2Values.put(matcher.group(1), insideString!= null ? insideString : value); idx = matcher.end(); } return hint2Values; diff --git a/java/java.editor/src/org/netbeans/modules/java/editor/resources/Bundle.properties b/java/java.editor/src/org/netbeans/modules/java/editor/resources/Bundle.properties index b1b2ef3..1816240 100644 --- a/java/java.editor/src/org/netbeans/modules/java/editor/resources/Bundle.properties +++ b/java/java.editor/src/org/netbeans/modules/java/editor/resources/Bundle.properties @@ -89,6 +89,10 @@ remove-surround-code-remain=Remove Surrounding Code (part to keep) # Code Templates CT_iff=if (<b>exp</b>) { ...| } CT_ifelse=if (<b>exp</b>) { ...| } else { ... } +CT_sw=switch (<b>exp</b>) { ...| } +CT_trycatch=try { ...| } catch(Exception e) { ... } +CT_trycatchfin=try { ...| } catch(Exception e) { ... } finally { ... } +CT_tryfin=try { ...| } finally { ... } CT_form=for (Map.Entry<KeyType, ValueType> <b>entry</b> : <b>map</b>.entrySet()) { ... CT_bcom=/* ... */ diff --git a/java/java.editor/src/org/netbeans/modules/java/editor/resources/DefaultAbbrevs.xml b/java/java.editor/src/org/netbeans/modules/java/editor/resources/DefaultAbbrevs.xml index 45d9e3c..0f65c96 100644 --- a/java/java.editor/src/org/netbeans/modules/java/editor/resources/DefaultAbbrevs.xml +++ b/java/java.editor/src/org/netbeans/modules/java/editor/resources/DefaultAbbrevs.xml @@ -58,7 +58,7 @@ <codetemplate abbreviation="serr" contexts="BLOCK,CASE,LABELED_STATEMENT,DO_WHILE_LOOP,ENHANCED_FOR_LOOP,FOR_LOOP,IF,WHILE_LOOP,LAMBDA_EXPRESSION"><code><![CDATA[System.err.println("${cursor}");]]></code></codetemplate> <codetemplate abbreviation="sout" contexts="BLOCK,CASE,LABELED_STATEMENT,DO_WHILE_LOOP,ENHANCED_FOR_LOOP,FOR_LOOP,IF,WHILE_LOOP,LAMBDA_EXPRESSION"><code><![CDATA[System.out.println("${cursor}");]]></code></codetemplate> <codetemplate abbreviation="st"><code><![CDATA[${no-indent}static ]]></code></codetemplate> - <codetemplate abbreviation="sw" contexts="BLOCK,CASE,LABELED_STATEMENT,DO_WHILE_LOOP,ENHANCED_FOR_LOOP,FOR_LOOP,IF,WHILE_LOOP,LAMBDA_EXPRESSION"> + <codetemplate abbreviation="sw" contexts="BLOCK,CASE,LABELED_STATEMENT,DO_WHILE_LOOP,ENHANCED_FOR_LOOP,FOR_LOOP,IF,WHILE_LOOP,LAMBDA_EXPRESSION" descriptionId="CT_sw"> <code> <![CDATA[switch (${var instanceof="java.lang.Enum"}) { case ${val completionInvoke}: @@ -91,7 +91,13 @@ } while (${expr instanceof="boolean" default="true"}); ]]></code></codetemplate> - <codetemplate abbreviation="sy"><code><![CDATA[${no-indent}synchronized ]]></code></codetemplate> + <codetemplate abbreviation="sy" contexts="BLOCK,CASE,LABELED_STATEMENT,DO_WHILE_LOOP,ENHANCED_FOR_LOOP,FOR_LOOP,IF,WHILE_LOOP,LAMBDA_EXPRESSION"> + <code> +<![CDATA[synchronized (${OBJ instanceof="java.lang.Object" default="this"}) { + ${selection}${cursor} +}]]> + </code> + </codetemplate> <codetemplate abbreviation="tds"><code><![CDATA[Thread.dumpStack();]]></code></codetemplate> <codetemplate abbreviation="th"><code><![CDATA[${no-indent}throws ]]></code></codetemplate> <codetemplate abbreviation="En"><code><![CDATA[${no-indent}Enumeration]]></code></codetemplate> @@ -250,11 +256,31 @@ ]]> </code> </codetemplate> - <codetemplate abbreviation="trycatch" contexts="BLOCK,CASE,LABELED_STATEMENT,DO_WHILE_LOOP,ENHANCED_FOR_LOOP,FOR_LOOP,IF,WHILE_LOOP,LAMBDA_EXPRESSION"> + <codetemplate abbreviation="trycatch" contexts="BLOCK,CASE,LABELED_STATEMENT,DO_WHILE_LOOP,ENHANCED_FOR_LOOP,FOR_LOOP,IF,WHILE_LOOP,LAMBDA_EXPRESSION" descriptionId="CT_trycatch"> <code> <![CDATA[try { ${selection}${cursor} -} ${CATCH_STMTS uncaughtExceptionCatchStatements default="catch (Exception e) {}" editable=false} +} ${CATCH_STMTS uncaughtExceptionCatchStatements default="catch (Exception e) { +}" editable=false} +]]> + </code> + </codetemplate> + <codetemplate abbreviation="trycatchfin" contexts="BLOCK,CASE,LABELED_STATEMENT,DO_WHILE_LOOP,ENHANCED_FOR_LOOP,FOR_LOOP,IF,WHILE_LOOP,LAMBDA_EXPRESSION" descriptionId="CT_trycatchfin"> + <code> +<![CDATA[try { + ${selection}${cursor} +} ${CATCH_STMTS uncaughtExceptionCatchStatements default="catch (Exception e) { +}" editable=false} finally { +} +]]> + </code> + </codetemplate> + <codetemplate abbreviation="tryfin" contexts="BLOCK,CASE,LABELED_STATEMENT,DO_WHILE_LOOP,ENHANCED_FOR_LOOP,FOR_LOOP,IF,WHILE_LOOP,LAMBDA_EXPRESSION" descriptionId="CT_tryfin"> + <code> +<![CDATA[try { + ${selection}${cursor} +} finally { +} ]]> </code> </codetemplate> diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/SurroundWithHint.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/SurroundWithHint.java index 904815d..5aad8d4 100644 --- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/SurroundWithHint.java +++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/SurroundWithHint.java @@ -29,6 +29,7 @@ import com.sun.source.util.Trees; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.EnumSet; @@ -79,24 +80,28 @@ import org.openide.util.lookup.ServiceProvider; public final class SurroundWithHint extends CodeActionsProvider { private static final String COMMAND_INSERT_SNIPPET = "editor.action.insertSnippet"; + private static final String COMMAND_SURROUND_WITH = "java.surround.with"; private static final String DOTS = "..."; private static final String SNIPPET = "snippet"; private static final String SELECTION_VAR = "${selection}"; private static final String SELECTED_TEXT_VAR = "${0:$TM_SELECTED_TEXT}"; - private static final Pattern SNIPPET_VAR_PATTERN = Pattern.compile("\\$\\{\\s*([-\\w]++)([^}]*)?}"); - private static final Pattern SNIPPET_HINT_PATTERN = Pattern.compile("([-\\w]++)(?:\\s*=\\s*(\\\"([^\\\"]*)\\\"|\\S*))?"); + private static final Pattern SNIPPET_VAR_PATTERN = Pattern.compile("\\$\\{\\s*([-\\w]++)((?:\\s*[-\\w]++(?:\\s*=\\s*(?:\\\"[^\\\"]*\\\"|[-\\w]++))?)*\\s*)?}"); + private static final Pattern SNIPPET_HINT_PATTERN = Pattern.compile("([-\\w]++)(?:\\s*=\\s*(\\\"([^\\\"]*)\\\"|[-\\w]++))?"); + private static final String UNCAUGHT_EXCEPTION_CATCH_STATEMENTS = "uncaughtExceptionCatchStatements"; private static final Set<String> TO_FILTER = Collections.singleton("fcom"); + private static final Set<String> TO_SHOW = Collections.unmodifiableSet(new HashSet(Arrays.asList("bcom", "dowhile", "iff", "fore", "sy", "trycatch", "whilexp"))); @Override @NbBundle.Messages({ - "DN_SurroundWith=Surround with \"{0}\"", + "DN_SurroundWith=Surround with {0}", + "DN_SurroundWithAll=Surround with ...", }) public List<CodeAction> getCodeActions(ResultIterator resultIterator, CodeActionParams params) throws Exception { CompilationController info = CompilationController.get(resultIterator.getParserResult()); if (info == null) { return Collections.emptyList(); } - info.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED); + info.toPhase(JavaSource.Phase.RESOLVED); int startOffset = getOffset(info, params.getRange().getStart()); int endOffset = getOffset(info, params.getRange().getEnd()); if (startOffset >= endOffset) { @@ -110,6 +115,7 @@ public final class SurroundWithHint extends CodeActionsProvider { } Collection<? extends CodeTemplateFilter> filters = getTemplateFilters(doc, startOffset, endOffset); List<CodeAction> codeActions = new ArrayList<>(); + List<QuickPickItem> items = new ArrayList<>(); for (CodeTemplate codeTemplate : CodeTemplateManager.get(doc).getCodeTemplates()) { String parametrizedText = codeTemplate.getParametrizedText(); if (parametrizedText.toLowerCase().contains(SELECTION_VAR) && !TO_FILTER.contains(codeTemplate.getAbbreviation())) { @@ -127,14 +133,21 @@ public final class SurroundWithHint extends CodeActionsProvider { if (sb.length() > 0) { snippet = sb.append(snippet).toString(); } - CodeAction codeAction = createCodeAction(Bundle.DN_SurroundWith(label), CodeActionKind.RefactorRewrite, COMMAND_INSERT_SNIPPET, Collections.singletonMap(SNIPPET, snippet)); + int idx = label.indexOf(' '); + CodeAction codeAction = createCodeAction(Bundle.DN_SurroundWith(idx < 0 ? label : label.substring(0, idx)), CodeActionKind.RefactorRewrite, COMMAND_INSERT_SNIPPET, Collections.singletonMap(SNIPPET, snippet)); if (!edits.isEmpty()) { codeAction.setEdit(new WorkspaceEdit(Collections.singletonMap(params.getTextDocument().getUri(), edits))); } - codeActions.add(codeAction); + if (TO_SHOW.contains(codeTemplate.getAbbreviation())) { + codeActions.add(codeAction); + } + items.add(new QuickPickItem(label, null, text, false, codeAction)); } } } + if (items.size() > codeActions.size()) { + codeActions.add(createCodeAction(Bundle.DN_SurroundWithAll(), CodeActionKind.RefactorRewrite, COMMAND_SURROUND_WITH, items)); + } return codeActions; } @@ -184,7 +197,9 @@ public final class SurroundWithHint extends CodeActionsProvider { case CodeTemplateParameter.NO_INDENT_PARAMETER_NAME: break; case CodeTemplateParameter.SELECTION_PARAMETER_NAME: - if (last != null) { + if (last == null) { + sb.append(' '); + } else { sb.append(SELECTED_TEXT_VAR); } break; @@ -202,7 +217,13 @@ public final class SurroundWithHint extends CodeActionsProvider { if (defaultValue != null) { values.put(name, defaultValue); } - if ("false".equalsIgnoreCase(hints.get(CodeTemplateParameter.EDITABLE_HINT_NAME))) { + if (hints.containsKey(UNCAUGHT_EXCEPTION_CATCH_STATEMENTS)) { + if (last == null) { + sb.append(defaultValue); + } else { + sb.append("catch (${").append(last.incrementAndGet()).append(":Exception} ${").append(last.incrementAndGet()).append(":e}) {\n}"); + } + } else if ("false".equalsIgnoreCase(hints.get(CodeTemplateParameter.EDITABLE_HINT_NAME))) { nonEditables.add(name); sb.append(values.getOrDefault(name, "")); } else { @@ -231,7 +252,9 @@ public final class SurroundWithHint extends CodeActionsProvider { Matcher matcher = SNIPPET_HINT_PATTERN.matcher(text); int idx = 0; while (matcher.find(idx)) { - hint2Values.put(matcher.group(1), matcher.groupCount() > 2 ? matcher.group(3) : matcher.groupCount() > 1 ? matcher.group(2) : null); + String insideString = matcher.groupCount() > 2 ? matcher.group(3) : null; + String value = matcher.groupCount() > 1 ? matcher.group(2) : null; + hint2Values.put(matcher.group(1), insideString!= null ? insideString : value); idx = matcher.end(); } return hint2Values; diff --git a/java/java.lsp.server/vscode/src/extension.ts b/java/java.lsp.server/vscode/src/extension.ts index 706d66b..2b6723c 100644 --- a/java/java.lsp.server/vscode/src/extension.ts +++ b/java/java.lsp.server/vscode/src/extension.ts @@ -288,6 +288,23 @@ export function activate(context: ExtensionContext): VSNetBeansAPI { ]); } })); + context.subscriptions.push(commands.registerCommand('java.surround.with', async (items) => { + const selected: any = await window.showQuickPick(items, { placeHolder: 'Surround with ...' }); + if (selected) { + if (selected.userData.edit && selected.userData.edit.changes) { + let edit = new vscode.WorkspaceEdit(); + Object.keys(selected.userData.edit.changes).forEach(key => { + edit.set(vscode.Uri.parse(key), selected.userData.edit.changes[key].map((change: any) => { + let start = new vscode.Position(change.range.start.line, change.range.start.character); + let end = new vscode.Position(change.range.end.line, change.range.end.character); + return new vscode.TextEdit(new vscode.Range(start, end), change.newText); + })); + }); + await workspace.applyEdit(edit); + } + await commands.executeCommand(selected.userData.command.command, ...(selected.userData.command.arguments || [])); + } + })); const runDebug = async (noDebug: boolean, testRun: boolean, uri: string, methodName?: string, launchConfiguration?: string) => { const docUri = uri ? vscode.Uri.file(uri) : window.activeTextEditor?.document.uri; if (docUri) { --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org For additional commands, e-mail: commits-h...@netbeans.apache.org For further information about the NetBeans mailing lists, visit: https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists