From 1a0a2d374a68e5606fdc6887bb7208535107fc8f Mon Sep 17 00:00:00 2001 From: Dusan Balek Date: Thu, 9 Dec 2021 09:55:11 +0100 Subject: [PATCH 1/4] Using HTML based UI for Change method parameters refactoring --- java/java.lsp.server/licenseinfo.xml | 5 + .../ChangeMethodParametersRefactoring.java | 273 ---------- .../server/protocol/CodeActionsProvider.java | 4 +- .../ChangeMethodParametersRefactoring.java | 363 +++++++++++++ .../CodeRefactoring.java | 5 +- ...tractSuperclassOrInterfaceRefactoring.java | 7 +- .../MoveRefactoring.java | 6 +- .../PullUpRefactoring.java | 6 +- .../PushDownRefactoring.java | 6 +- .../ui/ChangeMethodParameters.html | 79 +++ .../lsp/server/refactoring/ui/codicon.css | 485 ++++++++++++++++++ .../lsp/server/refactoring/ui/codicon.ttf | Bin 0 -> 65608 bytes .../lsp/server/refactoring/ui/refactoring.css | 169 ++++++ .../java/lsp/server/protocol/ServerTest.java | 4 + 14 files changed, 1131 insertions(+), 281 deletions(-) delete mode 100644 java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/ChangeMethodParametersRefactoring.java create mode 100644 java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/ChangeMethodParametersRefactoring.java rename java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/{protocol => refactoring}/CodeRefactoring.java (96%) rename java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/{protocol => refactoring}/ExtractSuperclassOrInterfaceRefactoring.java (96%) rename java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/{protocol => refactoring}/MoveRefactoring.java (97%) rename java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/{protocol => refactoring}/PullUpRefactoring.java (97%) rename java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/{protocol => refactoring}/PushDownRefactoring.java (96%) create mode 100644 java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/ui/ChangeMethodParameters.html create mode 100644 java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/ui/codicon.css create mode 100644 java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/ui/codicon.ttf create mode 100644 java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/ui/refactoring.css diff --git a/java/java.lsp.server/licenseinfo.xml b/java/java.lsp.server/licenseinfo.xml index f98f29338b9b..b2f957aee746 100644 --- a/java/java.lsp.server/licenseinfo.xml +++ b/java/java.lsp.server/licenseinfo.xml @@ -27,6 +27,11 @@ vscode/src/extension.ts + + src/org/netbeans/modules/java/lsp/server/refactoring/ui/codicon.ttf + src/org/netbeans/modules/java/lsp/server/refactoring/ui/codicon.css + + vscode/.vscodeignore vscode/.eslintrc.json diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/ChangeMethodParametersRefactoring.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/ChangeMethodParametersRefactoring.java deleted file mode 100644 index 157fdce6753a..000000000000 --- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/ChangeMethodParametersRefactoring.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.netbeans.modules.java.lsp.server.protocol; - -import com.google.gson.Gson; -import com.sun.source.tree.BlockTree; -import com.sun.source.tree.ClassTree; -import com.sun.source.tree.StatementTree; -import com.sun.source.tree.Tree; -import com.sun.source.util.SourcePositions; -import com.sun.source.util.TreePath; -import com.sun.source.util.Trees; -import java.io.IOException; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.atomic.AtomicReference; -import javax.lang.model.element.Element; -import javax.lang.model.element.ElementKind; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.VariableElement; -import javax.lang.model.type.TypeKind; -import org.eclipse.lsp4j.ApplyWorkspaceEditParams; -import org.eclipse.lsp4j.CodeAction; -import org.eclipse.lsp4j.CodeActionKind; -import org.eclipse.lsp4j.CodeActionParams; -import org.eclipse.lsp4j.MessageParams; -import org.eclipse.lsp4j.MessageType; -import org.netbeans.api.java.source.ClasspathInfo; -import org.netbeans.api.java.source.CompilationController; -import org.netbeans.api.java.source.CompilationInfo; -import org.netbeans.api.java.source.ElementHandle; -import org.netbeans.api.java.source.JavaSource; -import org.netbeans.api.java.source.SourceUtils; -import org.netbeans.api.java.source.TreePathHandle; -import org.netbeans.api.java.source.TreeUtilities; -import org.netbeans.modules.editor.java.Utilities; -import org.netbeans.modules.java.lsp.server.Utils; -import org.netbeans.modules.parsing.api.ResultIterator; -import org.netbeans.modules.refactoring.java.api.ChangeParametersRefactoring; -import org.netbeans.modules.refactoring.java.api.JavaRefactoringUtils; -import org.openide.filesystems.FileObject; -import org.openide.util.NbBundle; -import org.openide.util.lookup.ServiceProvider; - -/** - * - * @author Dusan Balek - */ -@ServiceProvider(service = CodeActionsProvider.class, position = 200) -public final class ChangeMethodParametersRefactoring extends CodeRefactoring { - - private static final String CHANGE_METHOD_PARAMS_REFACTORING_KIND = "refactor.change.method.params"; - private static final String CHANGE_METHOD_PARAMS_REFACTORING_COMMAND = "java.refactor.change.method.params"; - - private final Set commands = Collections.singleton(CHANGE_METHOD_PARAMS_REFACTORING_COMMAND); - private final Gson gson = new Gson(); - - @Override - @NbBundle.Messages({ - "DN_ChangeMethodParams=Change Method Parameters...", - }) - public List getCodeActions(ResultIterator resultIterator, CodeActionParams params) throws Exception { - List only = params.getContext().getOnly(); - if (only == null || !only.contains(CodeActionKind.Refactor)) { - return Collections.emptyList(); - } - CompilationController info = CompilationController.get(resultIterator.getParserResult()); - if (info == null || !JavaRefactoringUtils.isRefactorable(info.getFileObject())) { - return Collections.emptyList(); - } - info.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED); - int offset = getOffset(info, params.getRange().getStart()); - Trees trees = info.getTrees(); - TreePath path = info.getTreeUtilities().pathFor(offset); - Tree.Kind kind = null; - while (path != null && (kind = path.getLeaf().getKind()) != Tree.Kind.METHOD && kind != Tree.Kind.METHOD_INVOCATION && kind != Tree.Kind.NEW_CLASS && kind != Tree.Kind.MEMBER_REFERENCE) { - path = path.getParentPath(); - } - Element element = null; - FileObject elementSource = null; - if (kind == Tree.Kind.METHOD_INVOCATION || kind == Tree.Kind.NEW_CLASS || kind == Tree.Kind.MEMBER_REFERENCE) { - element = trees.getElement(path); - if (element == null || element.asType().getKind() == TypeKind.ERROR) { - return Collections.emptyList(); - } - elementSource = SourceUtils.getFile(ElementHandle.create(element), info.getClasspathInfo()); - } - if (elementSource == null) { - return Collections.emptyList(); - } - QuickPickItem elementItem = new QuickPickItem(createLabel(info, element, true)); - elementItem.setUserData(new ElementData(element)); - return Collections.singletonList(createCodeAction(Bundle.DN_ChangeMethodParams(), CHANGE_METHOD_PARAMS_REFACTORING_KIND, null, CHANGE_METHOD_PARAMS_REFACTORING_COMMAND, Utils.toUri(elementSource), elementItem)); - } - - @Override - public Set getCommands() { - return commands; - } - - @Override - @NbBundle.Messages({ - "DN_ChangeMethodSignature=Change method signature", - }) - public CompletableFuture processCommand(NbCodeLanguageClient client, String command, List arguments) { - try { - if (arguments.size() > 1) { - String uri = gson.fromJson(gson.toJson(arguments.get(0)), String.class); - QuickPickItem sourceItem = gson.fromJson(gson.toJson(arguments.get(1)), QuickPickItem.class); - String label = sourceItem.getLabel(); - int idx = label.indexOf('('); - client.showInputBox(new ShowInputBoxParams(Bundle.DN_ChangeMethodSignature(), label.substring(idx))).thenAccept(signature -> { - if (signature != null && !signature.isEmpty()) { - changeMethodParams(client, uri, sourceItem, signature); - } - }); - } else { - throw new IllegalArgumentException(String.format("Illegal number of arguments received for command: %s", command)); - } - } catch (Exception ex) { - client.showMessage(new MessageParams(MessageType.Error, ex.getLocalizedMessage())); - } - return CompletableFuture.completedFuture(true); - } - - private void changeMethodParams(NbCodeLanguageClient client, String uri, QuickPickItem source, String signature) { - try { - FileObject file = Utils.fromUri(uri); - ClasspathInfo info = ClasspathInfo.create(file); - JavaSource js = JavaSource.forFileObject(file); - if (js == null) { - throw new IOException("Cannot get JavaSource for: " + uri); - } - ElementHandle handle = gson.fromJson(gson.toJson(source.getUserData()), ElementData.class).toHandle(); - AtomicReference params = new AtomicReference<>(); - StringBuilder ret = new StringBuilder(); - js.runUserActionTask(ci -> { - ci.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED); - ExecutableElement method = (ExecutableElement) handle.resolve(ci); - if (method != null) { - TreePath path = ci.getTrees().getPath(method); - if (path != null) { - ExecutableElement el = fromSignature(ci, signature, path); - if (el != null) { - if (method.getReturnType() != el.getReturnType()) { - ret.append(Utilities.getTypeName(ci, el.getReturnType(), true)); - } - params.set(matchParameters(ci, el.getParameters(), method.getParameters())); - } - } - } - }, true); - if (params.get() == null) { - throw new IllegalArgumentException("Error while parsing new method signature."); - } - ChangeParametersRefactoring refactoring = new ChangeParametersRefactoring(TreePathHandle.from(handle, info)); - refactoring.setReturnType(ret.length() > 0 ? ret.toString() : null); - refactoring.setParameterInfo(params.get()); - refactoring.getContext().add(JavaRefactoringUtils.getClasspathInfoFor(file)); - client.applyEdit(new ApplyWorkspaceEditParams(perform(refactoring, "ChangeMethodParameters"))); - } catch (Exception ex) { - client.showMessage(new MessageParams(MessageType.Error, ex.getLocalizedMessage())); - } - } - - private static ExecutableElement fromSignature(CompilationInfo info, String signature, TreePath path) { - int idx = signature.lastIndexOf(':'); - StringBuilder toParse = new StringBuilder("{class _X { public "); - if (idx < 0) { - toParse.append("_X").append(signature); - } else { - toParse.append(signature.substring(idx + 1)).append(" m").append(signature.substring(0, idx)); - } - toParse.append("{}}}"); - SourcePositions[] sp = new SourcePositions[1]; - TreeUtilities treeUtilities = info.getTreeUtilities(); - StatementTree stmt = treeUtilities.parseStatement(toParse.toString(), sp); - if (stmt != null && stmt.getKind() == Tree.Kind.BLOCK) { - treeUtilities.attributeTree(stmt, info.getTrees().getScope(path)); - List stmts = ((BlockTree) stmt).getStatements(); - if (!stmts.isEmpty() && stmts.get(0).getKind() == Tree.Kind.CLASS) { - ClassTree ct = (ClassTree) stmts.get(0); - for (Tree member : ct.getMembers()) { - TreePath memberPath = new TreePath(path, member); - if (!treeUtilities.isSynthetic(memberPath) && member.getKind() == Tree.Kind.METHOD) { - Element element = info.getTrees().getElement(memberPath); - if (element != null && (element.getKind() == ElementKind.METHOD || element.getKind() == ElementKind.CONSTRUCTOR)) { - return (ExecutableElement) element; - } - } - } - } - } - return null; - } - - private static ChangeParametersRefactoring.ParameterInfo[] matchParameters(CompilationInfo info, List params, List orig) { - ChangeParametersRefactoring.ParameterInfo[] result = new ChangeParametersRefactoring.ParameterInfo[params.size()]; - boolean[] used = new boolean[orig.size()]; - for (int idx = 0; idx < params.size(); idx++) { - VariableElement param = params.get(idx); - for (int i = 0; i < orig.size(); i++) { - if (!used[i]) { - VariableElement origParam = orig.get(i); - if (origParam.getSimpleName().contentEquals(param.getSimpleName())) { - result[idx] = new ChangeParametersRefactoring.ParameterInfo(i, param.getSimpleName().toString(), Utilities.getTypeName(info, param.asType(), true).toString(), null); - used[i] = true; - } - } - } - } - for (int idx = 0; idx < params.size(); idx++) { - if (result[idx] == null) { - VariableElement param = params.get(idx); - for (int i = 0; i < orig.size(); i++) { - if (!used[i]) { - VariableElement origParam = orig.get(i); - if (origParam.asType() == param.asType()) { - result[idx] = new ChangeParametersRefactoring.ParameterInfo(i, param.getSimpleName().toString(), Utilities.getTypeName(info, param.asType(), true).toString(), null); - used[i] = true; - } - } - } - } - } - for (int idx = 0; idx < params.size(); idx++) { - if (result[idx] == null) { - VariableElement param = params.get(idx); - result[idx] = idx >= orig.size() || used[idx] - ? new ChangeParametersRefactoring.ParameterInfo(-1, param.getSimpleName().toString(), Utilities.getTypeName(info, param.asType(), true).toString(), defaultValue(param)) - : new ChangeParametersRefactoring.ParameterInfo(idx, param.getSimpleName().toString(), Utilities.getTypeName(info, param.asType(), true).toString(), null); - } - } - return result; - } - - private static String defaultValue(VariableElement param) { - switch(param.asType().getKind()) { - case ARRAY: - case DECLARED: - return "null"; - case BOOLEAN: - return "false"; - case BYTE: - case CHAR: - case DOUBLE: - case FLOAT: - case INT: - case LONG: - case SHORT: - return "0"; - } - return null; - } -} diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/CodeActionsProvider.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/CodeActionsProvider.java index 5ea0ec7a9523..30910a4cf67c 100644 --- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/CodeActionsProvider.java +++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/CodeActionsProvider.java @@ -159,11 +159,11 @@ public ElementData(ElementHandle handle) { this.signature = ElementHandleAccessor.getInstance().getJVMSignature(handle); } - ElementHandle toHandle() { + public ElementHandle toHandle() { return ElementHandleAccessor.getInstance().create(ElementKind.valueOf(kind), signature); } - Element resolve(CompilationInfo info) { + public Element resolve(CompilationInfo info) { return toHandle().resolve(info); } diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/ChangeMethodParametersRefactoring.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/ChangeMethodParametersRefactoring.java new file mode 100644 index 000000000000..627a9611e766 --- /dev/null +++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/ChangeMethodParametersRefactoring.java @@ -0,0 +1,363 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.java.lsp.server.refactoring; + +import com.google.gson.Gson; +import com.sun.source.tree.Tree; +import com.sun.source.util.TreePath; +import com.sun.source.util.Trees; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.function.BiConsumer; +import java.util.logging.Level; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.TypeKind; +import net.java.html.json.ComputedProperty; +import net.java.html.json.Function; +import net.java.html.json.Model; +import net.java.html.json.ModelOperation; +import net.java.html.json.Property; +import org.eclipse.lsp4j.ApplyWorkspaceEditParams; +import org.eclipse.lsp4j.CodeAction; +import org.eclipse.lsp4j.CodeActionKind; +import org.eclipse.lsp4j.CodeActionParams; +import org.eclipse.lsp4j.MessageParams; +import org.eclipse.lsp4j.MessageType; +import org.netbeans.api.htmlui.HTMLDialog; +import org.netbeans.api.java.source.ClasspathInfo; +import org.netbeans.api.java.source.CompilationController; +import org.netbeans.api.java.source.ElementHandle; +import org.netbeans.api.java.source.JavaSource; +import org.netbeans.api.java.source.SourceUtils; +import org.netbeans.api.java.source.TreePathHandle; +import org.netbeans.modules.editor.java.Utilities; +import org.netbeans.modules.java.lsp.server.Utils; +import org.netbeans.modules.java.lsp.server.protocol.CodeActionsProvider; +import org.netbeans.modules.java.lsp.server.protocol.NbCodeLanguageClient; +import org.netbeans.modules.java.lsp.server.protocol.QuickPickItem; +import org.netbeans.modules.parsing.api.ResultIterator; +import org.netbeans.modules.refactoring.java.api.ChangeParametersRefactoring; +import org.netbeans.modules.refactoring.java.api.JavaRefactoringUtils; +import org.openide.filesystems.FileObject; +import org.openide.util.Exceptions; +import org.openide.util.NbBundle; +import org.openide.util.RequestProcessor; +import org.openide.util.lookup.ServiceProvider; + +/** + * + * @author Dusan Balek + */ +@ServiceProvider(service = CodeActionsProvider.class, position = 200) +public final class ChangeMethodParametersRefactoring extends CodeRefactoring { + + private static final String CHANGE_METHOD_PARAMS_REFACTORING_KIND = "refactor.change.method.params"; + private static final String CHANGE_METHOD_PARAMS_REFACTORING_COMMAND = "java.refactor.change.method.params"; + + private final Set commands = Collections.singleton(CHANGE_METHOD_PARAMS_REFACTORING_COMMAND); + private final Gson gson = new Gson(); + + @Override + @NbBundle.Messages({ + "DN_ChangeMethodParams=Change Method Parameters...", + }) + public List getCodeActions(ResultIterator resultIterator, CodeActionParams params) throws Exception { + List only = params.getContext().getOnly(); + if (only == null || !only.contains(CodeActionKind.Refactor)) { + return Collections.emptyList(); + } + CompilationController info = CompilationController.get(resultIterator.getParserResult()); + if (info == null || !JavaRefactoringUtils.isRefactorable(info.getFileObject())) { + return Collections.emptyList(); + } + info.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED); + int offset = getOffset(info, params.getRange().getStart()); + Trees trees = info.getTrees(); + TreePath path = info.getTreeUtilities().pathFor(offset); + Tree.Kind kind = null; + while (path != null && (kind = path.getLeaf().getKind()) != Tree.Kind.METHOD && kind != Tree.Kind.METHOD_INVOCATION && kind != Tree.Kind.NEW_CLASS && kind != Tree.Kind.MEMBER_REFERENCE) { + path = path.getParentPath(); + } + Element element = null; + FileObject elementSource = null; + if (kind == Tree.Kind.METHOD || kind == Tree.Kind.METHOD_INVOCATION || kind == Tree.Kind.NEW_CLASS || kind == Tree.Kind.MEMBER_REFERENCE) { + element = trees.getElement(path); + if (element == null || element.asType().getKind() == TypeKind.ERROR) { + return Collections.emptyList(); + } + elementSource = SourceUtils.getFile(ElementHandle.create(element), info.getClasspathInfo()); + } + if (elementSource == null) { + return Collections.emptyList(); + } + QuickPickItem elementItem = new QuickPickItem(createLabel(info, element, true)); + elementItem.setUserData(new ElementData(element)); + return Collections.singletonList(createCodeAction(Bundle.DN_ChangeMethodParams(), CHANGE_METHOD_PARAMS_REFACTORING_KIND, null, CHANGE_METHOD_PARAMS_REFACTORING_COMMAND, Utils.toUri(elementSource), elementItem)); + } + + @Override + public Set getCommands() { + return commands; + } + + @Override + @NbBundle.Messages({ + "DN_ChangeMethodSignature=Change method signature", + }) + public CompletableFuture processCommand(NbCodeLanguageClient client, String command, List arguments) { + try { + if (arguments.size() > 1) { + String uri = gson.fromJson(gson.toJson(arguments.get(0)), String.class); + QuickPickItem sourceItem = gson.fromJson(gson.toJson(arguments.get(1)), QuickPickItem.class); + ElementHandle handle = gson.fromJson(gson.toJson(sourceItem.getUserData()), ElementData.class).toHandle(); + FileObject file = Utils.fromUri(uri); + JavaSource js = JavaSource.forFileObject(file); + if (js != null) { + return CompletableFuture.supplyAsync(() -> { + try { + js.runUserActionTask(ci -> { + ci.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED); + ExecutableElement method = (ExecutableElement) handle.resolve(ci); + if (method != null) { + Pages.showChangeMethodParametersUI(ci, client, file, handle, method); + } + }, true); + return null; + } catch (IOException ex) { + throw new IllegalStateException(ex); + } + }, RequestProcessor.getDefault()); + } + } else { + throw new IllegalArgumentException(String.format("Illegal number of arguments received for command: %s", command)); + } + } catch (Exception ex) { + client.showMessage(new MessageParams(MessageType.Error, ex.getLocalizedMessage())); + } + return CompletableFuture.completedFuture(true); + } + + private static String defaultValue(String type) { + switch(type) { + case "boolean": + return "false"; + case "byte": + case "char": + case "double": + case "float": + case "int": + case "long": + case "short": + return "0"; + } + return "null"; + } + + @HTMLDialog(url = "ui/ChangeMethodParameters.html") + static HTMLDialog.OnSubmit showChangeMethodParametersUI( + CompilationController ci, + NbCodeLanguageClient client, + FileObject file, + ElementHandle handle, + ExecutableElement method + ) { + ParameterUI[] params = new ParameterUI[method.getParameters().size()]; + for (int i = 0; i < method.getParameters().size(); i++) { + VariableElement param = method.getParameters().get(i); + ChangeParametersRefactoring.ParameterInfo info = new ChangeParametersRefactoring.ParameterInfo(i, param.getSimpleName().toString(), Utilities.getTypeName(ci, param.asType(), true).toString(), null); + params[i] = new ParameterUI(info.getType(), info.getName()); + params[i].assignInfo(info); + } + Modifier mod; + if (method.getModifiers().contains(javax.lang.model.element.Modifier.PUBLIC)) { + mod = Modifier.PUBLIC; + } else if (method.getModifiers().contains(javax.lang.model.element.Modifier.PROTECTED)) { + mod = Modifier.PROTECTED; + } else if (method.getModifiers().contains(javax.lang.model.element.Modifier.PRIVATE)) { + mod = Modifier.PRIVATE; + } else { + mod = Modifier.PACKAGE_PRIVATE; + } + ChangeMethodParameterUI model = new ChangeMethodParameterUI(); + model.withName(method.getSimpleName().toString()) + .withReturnType(Utilities.getTypeName(ci, method.getReturnType(), true).toString()) + .withSelectedModifier(mod) + .withParameters(params) + .assignData(client, file, TreePathHandle.from(handle, ClasspathInfo.create(file))); + model.applyBindings(); + return (id) -> { + if ("accept".equals(id)) { + model.doRefactoring(); + } + return true; // return false, if validation fails + }; + } + + @Model(className = "ChangeMethodParameterUI", targetId = "", instance = true, builder = "with", properties = { + @Property(name = "selectedModifier", type = Modifier.class), + @Property(name = "name", type = String.class), + @Property(name = "returnType", type = String.class), + @Property(name = "parameters", type = ParameterUI.class, array = true) + }) + static final class MethodControl { + + private NbCodeLanguageClient client; + private FileObject file; + private TreePathHandle handle; + + @ModelOperation + void assignData(ChangeMethodParameterUI ui, NbCodeLanguageClient client, FileObject file, TreePathHandle handle) { + this.client = client; + this.file = file; + this.handle = handle; + } + + @ModelOperation + @Function + void doRefactoring(ChangeMethodParameterUI ui) { + try { + ChangeParametersRefactoring refactoring = new ChangeParametersRefactoring(handle); + String returnType = ui.getReturnType(); + refactoring.setReturnType(returnType.length() > 0 ? returnType : null); + List parameters = ui.getParameters(); + ChangeParametersRefactoring.ParameterInfo[] params = new ChangeParametersRefactoring.ParameterInfo[parameters.size()]; + for (int i = 0; i < parameters.size(); i++) { + ParameterUI parameter = parameters.get(i); + parameter.getInfo(i, (idx, info) -> { + if (info != null) { + params[idx] = new ChangeParametersRefactoring.ParameterInfo(info.getOriginalIndex(), parameter.getName(), parameter.getType(), null); + } else { + params[idx] = new ChangeParametersRefactoring.ParameterInfo(-1, parameter.getName(), parameter.getType(), defaultValue(parameter.getType())); + } + }); + } + refactoring.setParameterInfo(params); + refactoring.getContext().add(JavaRefactoringUtils.getClasspathInfoFor(file)); + client.applyEdit(new ApplyWorkspaceEditParams(perform(refactoring, "ChangeMethodParameters"))); + } catch (Exception ex) { + if (client == null) { + Exceptions.printStackTrace( + Exceptions.attachSeverity(ex, Level.SEVERE) + ); + } else { + client.showMessage(new MessageParams(MessageType.Error, ex.getLocalizedMessage())); + } + } + } + + @Function + void moveUpParameter(ChangeMethodParameterUI ui, ParameterUI data) { + final List arr = ui.getParameters(); + int index = arr.indexOf(data); + if (index > 0) { + ParameterUI other = arr.get(index - 1); + arr.set(index, other); + arr.set(index - 1, data); + } + } + + @Function + void moveDownParameter(ChangeMethodParameterUI ui, ParameterUI data) { + final List arr = ui.getParameters(); + int index = arr.indexOf(data); + if (index != -1 && index + 1 < arr.size()) { + ParameterUI other = arr.get(index + 1); + arr.set(index, other); + arr.set(index + 1, data); + } + } + + @Function + void addParameter(ChangeMethodParameterUI ui) { + ui.getParameters().add(new ParameterUI()); + } + + @Function + void removeParameter(ChangeMethodParameterUI ui, ParameterUI data) { + ui.getParameters().remove(data); + } + + @ComputedProperty + static List availableModifiers() { + return Arrays.asList(Modifier.values()); + } + + @ComputedProperty + static String preview( + Modifier selectedModifier, String returnType, String name, List parameters + ) { + StringBuilder sb = new StringBuilder(); + sb.append(selectedModifier != null ? selectedModifier.javaName : "").append(" ").append(returnType); + sb.append(" ").append(name).append("("); + String sep = ""; + for (ParameterUI p : parameters) { + sb.append(sep); + sb.append(p.getType()).append(" ").append(p.getName()); + sep = ", "; + } + sb.append(")"); + return sb.toString(); + } + } + + @Model(className = "ParameterUI", instance = true, properties = { + @Property(name = "type", type = String.class), + @Property(name = "name", type = String.class) + }) + static final class ParamControl { + private ChangeParametersRefactoring.ParameterInfo info; + + @ModelOperation + void assignInfo(ParameterUI model, ChangeParametersRefactoring.ParameterInfo info) { + this.info = info; + } + + @ModelOperation + void getInfo(ParameterUI model, int idx, BiConsumer consumer) { + consumer.accept(idx, info); + } + } + + public static enum Modifier { + PUBLIC("public"), PROTECTED("protected"), PACKAGE_PRIVATE("", "package private"), PRIVATE("private"); + + final String javaName; + final String humanName; + + Modifier(String javaName) { + this(javaName, null); + } + + Modifier(String javaName, String humanName) { + this.javaName = javaName; + this.humanName = humanName; + } + + @Override + public String toString() { + return humanName == null ? javaName : humanName; + } + } +} diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/CodeRefactoring.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/CodeRefactoring.java similarity index 96% rename from java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/CodeRefactoring.java rename to java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/CodeRefactoring.java index 01494f56b8e7..15545494df6d 100644 --- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/CodeRefactoring.java +++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/CodeRefactoring.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.netbeans.modules.java.lsp.server.protocol; +package org.netbeans.modules.java.lsp.server.refactoring; import java.io.File; import java.net.URL; @@ -39,6 +39,7 @@ import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.netbeans.api.java.source.ModificationResult; import org.netbeans.modules.java.lsp.server.Utils; +import org.netbeans.modules.java.lsp.server.protocol.CodeActionsProvider; import org.netbeans.modules.refactoring.api.AbstractRefactoring; import org.netbeans.modules.refactoring.api.Problem; import org.netbeans.modules.refactoring.api.RefactoringSession; @@ -57,7 +58,7 @@ */ public abstract class CodeRefactoring extends CodeActionsProvider { - protected final WorkspaceEdit perform(AbstractRefactoring refactoring, String name) throws Exception { + protected static final WorkspaceEdit perform(AbstractRefactoring refactoring, String name) throws Exception { RefactoringSession session = RefactoringSession.create(name); Problem p = refactoring.checkParameters(); if (p != null && p.isFatal()) { diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/ExtractSuperclassOrInterfaceRefactoring.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/ExtractSuperclassOrInterfaceRefactoring.java similarity index 96% rename from java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/ExtractSuperclassOrInterfaceRefactoring.java rename to java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/ExtractSuperclassOrInterfaceRefactoring.java index e1e09ec18d10..2bbf35187638 100644 --- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/ExtractSuperclassOrInterfaceRefactoring.java +++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/ExtractSuperclassOrInterfaceRefactoring.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.netbeans.modules.java.lsp.server.protocol; +package org.netbeans.modules.java.lsp.server.refactoring; import com.google.gson.Gson; import com.sun.source.tree.ClassTree; @@ -54,6 +54,11 @@ import org.netbeans.api.java.source.TreePathHandle; import org.netbeans.api.java.source.TreeUtilities; import org.netbeans.modules.java.lsp.server.Utils; +import org.netbeans.modules.java.lsp.server.protocol.CodeActionsProvider; +import org.netbeans.modules.java.lsp.server.protocol.NbCodeLanguageClient; +import org.netbeans.modules.java.lsp.server.protocol.QuickPickItem; +import org.netbeans.modules.java.lsp.server.protocol.ShowInputBoxParams; +import org.netbeans.modules.java.lsp.server.protocol.ShowQuickPickParams; import org.netbeans.modules.parsing.api.ResultIterator; import org.netbeans.modules.refactoring.api.AbstractRefactoring; import org.netbeans.modules.refactoring.java.api.ExtractInterfaceRefactoring; diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/MoveRefactoring.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/MoveRefactoring.java similarity index 97% rename from java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/MoveRefactoring.java rename to java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/MoveRefactoring.java index 51475e64e5f2..5554da0d0828 100644 --- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/MoveRefactoring.java +++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/MoveRefactoring.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.netbeans.modules.java.lsp.server.protocol; +package org.netbeans.modules.java.lsp.server.refactoring; import com.google.gson.Gson; import com.sun.source.tree.ClassTree; @@ -55,6 +55,10 @@ import org.netbeans.api.project.ProjectUtils; import org.netbeans.api.project.SourceGroup; import org.netbeans.modules.java.lsp.server.Utils; +import org.netbeans.modules.java.lsp.server.protocol.CodeActionsProvider; +import org.netbeans.modules.java.lsp.server.protocol.NbCodeLanguageClient; +import org.netbeans.modules.java.lsp.server.protocol.QuickPickItem; +import org.netbeans.modules.java.lsp.server.protocol.ShowQuickPickParams; import org.netbeans.modules.parsing.api.ResultIterator; import org.netbeans.modules.refactoring.java.api.JavaMoveMembersProperties; import org.netbeans.modules.refactoring.java.api.JavaRefactoringUtils; diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/PullUpRefactoring.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/PullUpRefactoring.java similarity index 97% rename from java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/PullUpRefactoring.java rename to java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/PullUpRefactoring.java index dea79b207b99..86ea3e774c58 100644 --- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/PullUpRefactoring.java +++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/PullUpRefactoring.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.netbeans.modules.java.lsp.server.protocol; +package org.netbeans.modules.java.lsp.server.refactoring; import com.google.gson.Gson; import com.sun.source.tree.ClassTree; @@ -55,6 +55,10 @@ import org.netbeans.api.java.source.TreePathHandle; import org.netbeans.api.java.source.TreeUtilities; import org.netbeans.modules.java.lsp.server.Utils; +import org.netbeans.modules.java.lsp.server.protocol.CodeActionsProvider; +import org.netbeans.modules.java.lsp.server.protocol.NbCodeLanguageClient; +import org.netbeans.modules.java.lsp.server.protocol.QuickPickItem; +import org.netbeans.modules.java.lsp.server.protocol.ShowQuickPickParams; import org.netbeans.modules.parsing.api.ResultIterator; import org.netbeans.modules.refactoring.java.api.JavaRefactoringUtils; import org.netbeans.modules.refactoring.java.api.MemberInfo; diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/PushDownRefactoring.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/PushDownRefactoring.java similarity index 96% rename from java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/PushDownRefactoring.java rename to java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/PushDownRefactoring.java index 65cc6fde5fff..8291d658a945 100644 --- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/PushDownRefactoring.java +++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/PushDownRefactoring.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.netbeans.modules.java.lsp.server.protocol; +package org.netbeans.modules.java.lsp.server.refactoring; import com.google.gson.Gson; import com.sun.source.tree.ClassTree; @@ -51,6 +51,10 @@ import org.netbeans.api.java.source.TreePathHandle; import org.netbeans.api.java.source.TreeUtilities; import org.netbeans.modules.java.lsp.server.Utils; +import org.netbeans.modules.java.lsp.server.protocol.CodeActionsProvider; +import org.netbeans.modules.java.lsp.server.protocol.NbCodeLanguageClient; +import org.netbeans.modules.java.lsp.server.protocol.QuickPickItem; +import org.netbeans.modules.java.lsp.server.protocol.ShowQuickPickParams; import org.netbeans.modules.parsing.api.ResultIterator; import org.netbeans.modules.refactoring.java.api.JavaRefactoringUtils; import org.netbeans.modules.refactoring.java.api.MemberInfo; diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/ui/ChangeMethodParameters.html b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/ui/ChangeMethodParameters.html new file mode 100644 index 000000000000..57d4508acee0 --- /dev/null +++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/ui/ChangeMethodParameters.html @@ -0,0 +1,79 @@ + + + + + + + + + + + Refactor: Change Method Parameters... + + + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + + +
+
+
+
+ + + + + +
+
+
+ +
+
+ +
+
+

+
+
+ + +
+ + diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/ui/codicon.css b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/ui/codicon.css new file mode 100644 index 000000000000..c2771b5e881e --- /dev/null +++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/ui/codicon.css @@ -0,0 +1,485 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +@font-face { + font-family: "codicon"; + src: url("./codicon.ttf?9642aa1d48ab4e55aa1bf3f0b8678aa1") format("truetype"); +} + +.codicon[class*='codicon-'] { + font: normal normal normal 16px/1 codicon; + display: inline-block; + text-decoration: none; + text-rendering: auto; + text-align: center; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + user-select: none; + -webkit-user-select: none; + -ms-user-select: none; +} + + +.codicon-add:before { content: "\ea60" } +.codicon-plus:before { content: "\ea60" } +.codicon-gist-new:before { content: "\ea60" } +.codicon-repo-create:before { content: "\ea60" } +.codicon-lightbulb:before { content: "\ea61" } +.codicon-light-bulb:before { content: "\ea61" } +.codicon-repo:before { content: "\ea62" } +.codicon-repo-delete:before { content: "\ea62" } +.codicon-gist-fork:before { content: "\ea63" } +.codicon-repo-forked:before { content: "\ea63" } +.codicon-git-pull-request:before { content: "\ea64" } +.codicon-git-pull-request-abandoned:before { content: "\ea64" } +.codicon-record-keys:before { content: "\ea65" } +.codicon-keyboard:before { content: "\ea65" } +.codicon-tag:before { content: "\ea66" } +.codicon-tag-add:before { content: "\ea66" } +.codicon-tag-remove:before { content: "\ea66" } +.codicon-person:before { content: "\ea67" } +.codicon-person-follow:before { content: "\ea67" } +.codicon-person-outline:before { content: "\ea67" } +.codicon-person-filled:before { content: "\ea67" } +.codicon-git-branch:before { content: "\ea68" } +.codicon-git-branch-create:before { content: "\ea68" } +.codicon-git-branch-delete:before { content: "\ea68" } +.codicon-source-control:before { content: "\ea68" } +.codicon-mirror:before { content: "\ea69" } +.codicon-mirror-public:before { content: "\ea69" } +.codicon-star:before { content: "\ea6a" } +.codicon-star-add:before { content: "\ea6a" } +.codicon-star-delete:before { content: "\ea6a" } +.codicon-star-empty:before { content: "\ea6a" } +.codicon-comment:before { content: "\ea6b" } +.codicon-comment-add:before { content: "\ea6b" } +.codicon-alert:before { content: "\ea6c" } +.codicon-warning:before { content: "\ea6c" } +.codicon-search:before { content: "\ea6d" } +.codicon-search-save:before { content: "\ea6d" } +.codicon-log-out:before { content: "\ea6e" } +.codicon-sign-out:before { content: "\ea6e" } +.codicon-log-in:before { content: "\ea6f" } +.codicon-sign-in:before { content: "\ea6f" } +.codicon-eye:before { content: "\ea70" } +.codicon-eye-unwatch:before { content: "\ea70" } +.codicon-eye-watch:before { content: "\ea70" } +.codicon-circle-filled:before { content: "\ea71" } +.codicon-primitive-dot:before { content: "\ea71" } +.codicon-close-dirty:before { content: "\ea71" } +.codicon-debug-breakpoint:before { content: "\ea71" } +.codicon-debug-breakpoint-disabled:before { content: "\ea71" } +.codicon-debug-hint:before { content: "\ea71" } +.codicon-primitive-square:before { content: "\ea72" } +.codicon-edit:before { content: "\ea73" } +.codicon-pencil:before { content: "\ea73" } +.codicon-info:before { content: "\ea74" } +.codicon-issue-opened:before { content: "\ea74" } +.codicon-gist-private:before { content: "\ea75" } +.codicon-git-fork-private:before { content: "\ea75" } +.codicon-lock:before { content: "\ea75" } +.codicon-mirror-private:before { content: "\ea75" } +.codicon-close:before { content: "\ea76" } +.codicon-remove-close:before { content: "\ea76" } +.codicon-x:before { content: "\ea76" } +.codicon-repo-sync:before { content: "\ea77" } +.codicon-sync:before { content: "\ea77" } +.codicon-clone:before { content: "\ea78" } +.codicon-desktop-download:before { content: "\ea78" } +.codicon-beaker:before { content: "\ea79" } +.codicon-microscope:before { content: "\ea79" } +.codicon-vm:before { content: "\ea7a" } +.codicon-device-desktop:before { content: "\ea7a" } +.codicon-file:before { content: "\ea7b" } +.codicon-file-text:before { content: "\ea7b" } +.codicon-more:before { content: "\ea7c" } +.codicon-ellipsis:before { content: "\ea7c" } +.codicon-kebab-horizontal:before { content: "\ea7c" } +.codicon-mail-reply:before { content: "\ea7d" } +.codicon-reply:before { content: "\ea7d" } +.codicon-organization:before { content: "\ea7e" } +.codicon-organization-filled:before { content: "\ea7e" } +.codicon-organization-outline:before { content: "\ea7e" } +.codicon-new-file:before { content: "\ea7f" } +.codicon-file-add:before { content: "\ea7f" } +.codicon-new-folder:before { content: "\ea80" } +.codicon-file-directory-create:before { content: "\ea80" } +.codicon-trash:before { content: "\ea81" } +.codicon-trashcan:before { content: "\ea81" } +.codicon-history:before { content: "\ea82" } +.codicon-clock:before { content: "\ea82" } +.codicon-folder:before { content: "\ea83" } +.codicon-file-directory:before { content: "\ea83" } +.codicon-symbol-folder:before { content: "\ea83" } +.codicon-logo-github:before { content: "\ea84" } +.codicon-mark-github:before { content: "\ea84" } +.codicon-github:before { content: "\ea84" } +.codicon-terminal:before { content: "\ea85" } +.codicon-console:before { content: "\ea85" } +.codicon-repl:before { content: "\ea85" } +.codicon-zap:before { content: "\ea86" } +.codicon-symbol-event:before { content: "\ea86" } +.codicon-error:before { content: "\ea87" } +.codicon-stop:before { content: "\ea87" } +.codicon-variable:before { content: "\ea88" } +.codicon-symbol-variable:before { content: "\ea88" } +.codicon-array:before { content: "\ea8a" } +.codicon-symbol-array:before { content: "\ea8a" } +.codicon-symbol-module:before { content: "\ea8b" } +.codicon-symbol-package:before { content: "\ea8b" } +.codicon-symbol-namespace:before { content: "\ea8b" } +.codicon-symbol-object:before { content: "\ea8b" } +.codicon-symbol-method:before { content: "\ea8c" } +.codicon-symbol-function:before { content: "\ea8c" } +.codicon-symbol-constructor:before { content: "\ea8c" } +.codicon-symbol-boolean:before { content: "\ea8f" } +.codicon-symbol-null:before { content: "\ea8f" } +.codicon-symbol-numeric:before { content: "\ea90" } +.codicon-symbol-number:before { content: "\ea90" } +.codicon-symbol-structure:before { content: "\ea91" } +.codicon-symbol-struct:before { content: "\ea91" } +.codicon-symbol-parameter:before { content: "\ea92" } +.codicon-symbol-type-parameter:before { content: "\ea92" } +.codicon-symbol-key:before { content: "\ea93" } +.codicon-symbol-text:before { content: "\ea93" } +.codicon-symbol-reference:before { content: "\ea94" } +.codicon-go-to-file:before { content: "\ea94" } +.codicon-symbol-enum:before { content: "\ea95" } +.codicon-symbol-value:before { content: "\ea95" } +.codicon-symbol-ruler:before { content: "\ea96" } +.codicon-symbol-unit:before { content: "\ea96" } +.codicon-activate-breakpoints:before { content: "\ea97" } +.codicon-archive:before { content: "\ea98" } +.codicon-arrow-both:before { content: "\ea99" } +.codicon-arrow-down:before { content: "\ea9a" } +.codicon-arrow-left:before { content: "\ea9b" } +.codicon-arrow-right:before { content: "\ea9c" } +.codicon-arrow-small-down:before { content: "\ea9d" } +.codicon-arrow-small-left:before { content: "\ea9e" } +.codicon-arrow-small-right:before { content: "\ea9f" } +.codicon-arrow-small-up:before { content: "\eaa0" } +.codicon-arrow-up:before { content: "\eaa1" } +.codicon-bell:before { content: "\eaa2" } +.codicon-bold:before { content: "\eaa3" } +.codicon-book:before { content: "\eaa4" } +.codicon-bookmark:before { content: "\eaa5" } +.codicon-debug-breakpoint-conditional-unverified:before { content: "\eaa6" } +.codicon-debug-breakpoint-conditional:before { content: "\eaa7" } +.codicon-debug-breakpoint-conditional-disabled:before { content: "\eaa7" } +.codicon-debug-breakpoint-data-unverified:before { content: "\eaa8" } +.codicon-debug-breakpoint-data:before { content: "\eaa9" } +.codicon-debug-breakpoint-data-disabled:before { content: "\eaa9" } +.codicon-debug-breakpoint-log-unverified:before { content: "\eaaa" } +.codicon-debug-breakpoint-log:before { content: "\eaab" } +.codicon-debug-breakpoint-log-disabled:before { content: "\eaab" } +.codicon-briefcase:before { content: "\eaac" } +.codicon-broadcast:before { content: "\eaad" } +.codicon-browser:before { content: "\eaae" } +.codicon-bug:before { content: "\eaaf" } +.codicon-calendar:before { content: "\eab0" } +.codicon-case-sensitive:before { content: "\eab1" } +.codicon-check:before { content: "\eab2" } +.codicon-checklist:before { content: "\eab3" } +.codicon-chevron-down:before { content: "\eab4" } +.codicon-chevron-left:before { content: "\eab5" } +.codicon-chevron-right:before { content: "\eab6" } +.codicon-chevron-up:before { content: "\eab7" } +.codicon-chrome-close:before { content: "\eab8" } +.codicon-chrome-maximize:before { content: "\eab9" } +.codicon-chrome-minimize:before { content: "\eaba" } +.codicon-chrome-restore:before { content: "\eabb" } +.codicon-circle-outline:before { content: "\eabc" } +.codicon-debug-breakpoint-unverified:before { content: "\eabc" } +.codicon-circle-slash:before { content: "\eabd" } +.codicon-circuit-board:before { content: "\eabe" } +.codicon-clear-all:before { content: "\eabf" } +.codicon-clippy:before { content: "\eac0" } +.codicon-close-all:before { content: "\eac1" } +.codicon-cloud-download:before { content: "\eac2" } +.codicon-cloud-upload:before { content: "\eac3" } +.codicon-code:before { content: "\eac4" } +.codicon-collapse-all:before { content: "\eac5" } +.codicon-color-mode:before { content: "\eac6" } +.codicon-comment-discussion:before { content: "\eac7" } +.codicon-credit-card:before { content: "\eac9" } +.codicon-dash:before { content: "\eacc" } +.codicon-dashboard:before { content: "\eacd" } +.codicon-database:before { content: "\eace" } +.codicon-debug-continue:before { content: "\eacf" } +.codicon-debug-disconnect:before { content: "\ead0" } +.codicon-debug-pause:before { content: "\ead1" } +.codicon-debug-restart:before { content: "\ead2" } +.codicon-debug-start:before { content: "\ead3" } +.codicon-debug-step-into:before { content: "\ead4" } +.codicon-debug-step-out:before { content: "\ead5" } +.codicon-debug-step-over:before { content: "\ead6" } +.codicon-debug-stop:before { content: "\ead7" } +.codicon-debug:before { content: "\ead8" } +.codicon-device-camera-video:before { content: "\ead9" } +.codicon-device-camera:before { content: "\eada" } +.codicon-device-mobile:before { content: "\eadb" } +.codicon-diff-added:before { content: "\eadc" } +.codicon-diff-ignored:before { content: "\eadd" } +.codicon-diff-modified:before { content: "\eade" } +.codicon-diff-removed:before { content: "\eadf" } +.codicon-diff-renamed:before { content: "\eae0" } +.codicon-diff:before { content: "\eae1" } +.codicon-discard:before { content: "\eae2" } +.codicon-editor-layout:before { content: "\eae3" } +.codicon-empty-window:before { content: "\eae4" } +.codicon-exclude:before { content: "\eae5" } +.codicon-extensions:before { content: "\eae6" } +.codicon-eye-closed:before { content: "\eae7" } +.codicon-file-binary:before { content: "\eae8" } +.codicon-file-code:before { content: "\eae9" } +.codicon-file-media:before { content: "\eaea" } +.codicon-file-pdf:before { content: "\eaeb" } +.codicon-file-submodule:before { content: "\eaec" } +.codicon-file-symlink-directory:before { content: "\eaed" } +.codicon-file-symlink-file:before { content: "\eaee" } +.codicon-file-zip:before { content: "\eaef" } +.codicon-files:before { content: "\eaf0" } +.codicon-filter:before { content: "\eaf1" } +.codicon-flame:before { content: "\eaf2" } +.codicon-fold-down:before { content: "\eaf3" } +.codicon-fold-up:before { content: "\eaf4" } +.codicon-fold:before { content: "\eaf5" } +.codicon-folder-active:before { content: "\eaf6" } +.codicon-folder-opened:before { content: "\eaf7" } +.codicon-gear:before { content: "\eaf8" } +.codicon-gift:before { content: "\eaf9" } +.codicon-gist-secret:before { content: "\eafa" } +.codicon-gist:before { content: "\eafb" } +.codicon-git-commit:before { content: "\eafc" } +.codicon-git-compare:before { content: "\eafd" } +.codicon-compare-changes:before { content: "\eafd" } +.codicon-git-merge:before { content: "\eafe" } +.codicon-github-action:before { content: "\eaff" } +.codicon-github-alt:before { content: "\eb00" } +.codicon-globe:before { content: "\eb01" } +.codicon-grabber:before { content: "\eb02" } +.codicon-graph:before { content: "\eb03" } +.codicon-gripper:before { content: "\eb04" } +.codicon-heart:before { content: "\eb05" } +.codicon-home:before { content: "\eb06" } +.codicon-horizontal-rule:before { content: "\eb07" } +.codicon-hubot:before { content: "\eb08" } +.codicon-inbox:before { content: "\eb09" } +.codicon-issue-reopened:before { content: "\eb0b" } +.codicon-issues:before { content: "\eb0c" } +.codicon-italic:before { content: "\eb0d" } +.codicon-jersey:before { content: "\eb0e" } +.codicon-json:before { content: "\eb0f" } +.codicon-kebab-vertical:before { content: "\eb10" } +.codicon-key:before { content: "\eb11" } +.codicon-law:before { content: "\eb12" } +.codicon-lightbulb-autofix:before { content: "\eb13" } +.codicon-link-external:before { content: "\eb14" } +.codicon-link:before { content: "\eb15" } +.codicon-list-ordered:before { content: "\eb16" } +.codicon-list-unordered:before { content: "\eb17" } +.codicon-live-share:before { content: "\eb18" } +.codicon-loading:before { content: "\eb19" } +.codicon-location:before { content: "\eb1a" } +.codicon-mail-read:before { content: "\eb1b" } +.codicon-mail:before { content: "\eb1c" } +.codicon-markdown:before { content: "\eb1d" } +.codicon-megaphone:before { content: "\eb1e" } +.codicon-mention:before { content: "\eb1f" } +.codicon-milestone:before { content: "\eb20" } +.codicon-mortar-board:before { content: "\eb21" } +.codicon-move:before { content: "\eb22" } +.codicon-multiple-windows:before { content: "\eb23" } +.codicon-mute:before { content: "\eb24" } +.codicon-no-newline:before { content: "\eb25" } +.codicon-note:before { content: "\eb26" } +.codicon-octoface:before { content: "\eb27" } +.codicon-open-preview:before { content: "\eb28" } +.codicon-package:before { content: "\eb29" } +.codicon-paintcan:before { content: "\eb2a" } +.codicon-pin:before { content: "\eb2b" } +.codicon-play:before { content: "\eb2c" } +.codicon-run:before { content: "\eb2c" } +.codicon-plug:before { content: "\eb2d" } +.codicon-preserve-case:before { content: "\eb2e" } +.codicon-preview:before { content: "\eb2f" } +.codicon-project:before { content: "\eb30" } +.codicon-pulse:before { content: "\eb31" } +.codicon-question:before { content: "\eb32" } +.codicon-quote:before { content: "\eb33" } +.codicon-radio-tower:before { content: "\eb34" } +.codicon-reactions:before { content: "\eb35" } +.codicon-references:before { content: "\eb36" } +.codicon-refresh:before { content: "\eb37" } +.codicon-regex:before { content: "\eb38" } +.codicon-remote-explorer:before { content: "\eb39" } +.codicon-remote:before { content: "\eb3a" } +.codicon-remove:before { content: "\eb3b" } +.codicon-replace-all:before { content: "\eb3c" } +.codicon-replace:before { content: "\eb3d" } +.codicon-repo-clone:before { content: "\eb3e" } +.codicon-repo-force-push:before { content: "\eb3f" } +.codicon-repo-pull:before { content: "\eb40" } +.codicon-repo-push:before { content: "\eb41" } +.codicon-report:before { content: "\eb42" } +.codicon-request-changes:before { content: "\eb43" } +.codicon-rocket:before { content: "\eb44" } +.codicon-root-folder-opened:before { content: "\eb45" } +.codicon-root-folder:before { content: "\eb46" } +.codicon-rss:before { content: "\eb47" } +.codicon-ruby:before { content: "\eb48" } +.codicon-save-all:before { content: "\eb49" } +.codicon-save-as:before { content: "\eb4a" } +.codicon-save:before { content: "\eb4b" } +.codicon-screen-full:before { content: "\eb4c" } +.codicon-screen-normal:before { content: "\eb4d" } +.codicon-search-stop:before { content: "\eb4e" } +.codicon-server:before { content: "\eb50" } +.codicon-settings-gear:before { content: "\eb51" } +.codicon-settings:before { content: "\eb52" } +.codicon-shield:before { content: "\eb53" } +.codicon-smiley:before { content: "\eb54" } +.codicon-sort-precedence:before { content: "\eb55" } +.codicon-split-horizontal:before { content: "\eb56" } +.codicon-split-vertical:before { content: "\eb57" } +.codicon-squirrel:before { content: "\eb58" } +.codicon-star-full:before { content: "\eb59" } +.codicon-star-half:before { content: "\eb5a" } +.codicon-symbol-class:before { content: "\eb5b" } +.codicon-symbol-color:before { content: "\eb5c" } +.codicon-symbol-constant:before { content: "\eb5d" } +.codicon-symbol-enum-member:before { content: "\eb5e" } +.codicon-symbol-field:before { content: "\eb5f" } +.codicon-symbol-file:before { content: "\eb60" } +.codicon-symbol-interface:before { content: "\eb61" } +.codicon-symbol-keyword:before { content: "\eb62" } +.codicon-symbol-misc:before { content: "\eb63" } +.codicon-symbol-operator:before { content: "\eb64" } +.codicon-symbol-property:before { content: "\eb65" } +.codicon-wrench:before { content: "\eb65" } +.codicon-wrench-subaction:before { content: "\eb65" } +.codicon-symbol-snippet:before { content: "\eb66" } +.codicon-tasklist:before { content: "\eb67" } +.codicon-telescope:before { content: "\eb68" } +.codicon-text-size:before { content: "\eb69" } +.codicon-three-bars:before { content: "\eb6a" } +.codicon-thumbsdown:before { content: "\eb6b" } +.codicon-thumbsup:before { content: "\eb6c" } +.codicon-tools:before { content: "\eb6d" } +.codicon-triangle-down:before { content: "\eb6e" } +.codicon-triangle-left:before { content: "\eb6f" } +.codicon-triangle-right:before { content: "\eb70" } +.codicon-triangle-up:before { content: "\eb71" } +.codicon-twitter:before { content: "\eb72" } +.codicon-unfold:before { content: "\eb73" } +.codicon-unlock:before { content: "\eb74" } +.codicon-unmute:before { content: "\eb75" } +.codicon-unverified:before { content: "\eb76" } +.codicon-verified:before { content: "\eb77" } +.codicon-versions:before { content: "\eb78" } +.codicon-vm-active:before { content: "\eb79" } +.codicon-vm-outline:before { content: "\eb7a" } +.codicon-vm-running:before { content: "\eb7b" } +.codicon-watch:before { content: "\eb7c" } +.codicon-whitespace:before { content: "\eb7d" } +.codicon-whole-word:before { content: "\eb7e" } +.codicon-window:before { content: "\eb7f" } +.codicon-word-wrap:before { content: "\eb80" } +.codicon-zoom-in:before { content: "\eb81" } +.codicon-zoom-out:before { content: "\eb82" } +.codicon-list-filter:before { content: "\eb83" } +.codicon-list-flat:before { content: "\eb84" } +.codicon-list-selection:before { content: "\eb85" } +.codicon-selection:before { content: "\eb85" } +.codicon-list-tree:before { content: "\eb86" } +.codicon-debug-breakpoint-function-unverified:before { content: "\eb87" } +.codicon-debug-breakpoint-function:before { content: "\eb88" } +.codicon-debug-breakpoint-function-disabled:before { content: "\eb88" } +.codicon-debug-stackframe-active:before { content: "\eb89" } +.codicon-debug-stackframe-dot:before { content: "\eb8a" } +.codicon-debug-stackframe:before { content: "\eb8b" } +.codicon-debug-stackframe-focused:before { content: "\eb8b" } +.codicon-debug-breakpoint-unsupported:before { content: "\eb8c" } +.codicon-symbol-string:before { content: "\eb8d" } +.codicon-debug-reverse-continue:before { content: "\eb8e" } +.codicon-debug-step-back:before { content: "\eb8f" } +.codicon-debug-restart-frame:before { content: "\eb90" } +.codicon-debug-alt:before { content: "\eb91" } +.codicon-call-incoming:before { content: "\eb92" } +.codicon-call-outgoing:before { content: "\eb93" } +.codicon-menu:before { content: "\eb94" } +.codicon-expand-all:before { content: "\eb95" } +.codicon-feedback:before { content: "\eb96" } +.codicon-group-by-ref-type:before { content: "\eb97" } +.codicon-ungroup-by-ref-type:before { content: "\eb98" } +.codicon-account:before { content: "\eb99" } +.codicon-bell-dot:before { content: "\eb9a" } +.codicon-debug-console:before { content: "\eb9b" } +.codicon-library:before { content: "\eb9c" } +.codicon-output:before { content: "\eb9d" } +.codicon-run-all:before { content: "\eb9e" } +.codicon-sync-ignored:before { content: "\eb9f" } +.codicon-pinned:before { content: "\eba0" } +.codicon-github-inverted:before { content: "\eba1" } +.codicon-server-process:before { content: "\eba2" } +.codicon-server-environment:before { content: "\eba3" } +.codicon-pass:before { content: "\eba4" } +.codicon-issue-closed:before { content: "\eba4" } +.codicon-stop-circle:before { content: "\eba5" } +.codicon-play-circle:before { content: "\eba6" } +.codicon-record:before { content: "\eba7" } +.codicon-debug-alt-small:before { content: "\eba8" } +.codicon-vm-connect:before { content: "\eba9" } +.codicon-cloud:before { content: "\ebaa" } +.codicon-merge:before { content: "\ebab" } +.codicon-export:before { content: "\ebac" } +.codicon-graph-left:before { content: "\ebad" } +.codicon-magnet:before { content: "\ebae" } +.codicon-notebook:before { content: "\ebaf" } +.codicon-redo:before { content: "\ebb0" } +.codicon-check-all:before { content: "\ebb1" } +.codicon-pinned-dirty:before { content: "\ebb2" } +.codicon-pass-filled:before { content: "\ebb3" } +.codicon-circle-large-filled:before { content: "\ebb4" } +.codicon-circle-large-outline:before { content: "\ebb5" } +.codicon-combine:before { content: "\ebb6" } +.codicon-gather:before { content: "\ebb6" } +.codicon-table:before { content: "\ebb7" } +.codicon-variable-group:before { content: "\ebb8" } +.codicon-type-hierarchy:before { content: "\ebb9" } +.codicon-type-hierarchy-sub:before { content: "\ebba" } +.codicon-type-hierarchy-super:before { content: "\ebbb" } +.codicon-git-pull-request-create:before { content: "\ebbc" } +.codicon-run-above:before { content: "\ebbd" } +.codicon-run-below:before { content: "\ebbe" } +.codicon-notebook-template:before { content: "\ebbf" } +.codicon-debug-rerun:before { content: "\ebc0" } +.codicon-workspace-trusted:before { content: "\ebc1" } +.codicon-workspace-untrusted:before { content: "\ebc2" } +.codicon-workspace-unknown:before { content: "\ebc3" } +.codicon-terminal-cmd:before { content: "\ebc4" } +.codicon-terminal-debian:before { content: "\ebc5" } +.codicon-terminal-linux:before { content: "\ebc6" } +.codicon-terminal-powershell:before { content: "\ebc7" } +.codicon-terminal-tmux:before { content: "\ebc8" } +.codicon-terminal-ubuntu:before { content: "\ebc9" } +.codicon-terminal-bash:before { content: "\ebca" } +.codicon-arrow-swap:before { content: "\ebcb" } +.codicon-copy:before { content: "\ebcc" } +.codicon-person-add:before { content: "\ebcd" } +.codicon-filter-filled:before { content: "\ebce" } +.codicon-wand:before { content: "\ebcf" } +.codicon-debug-line-by-line:before { content: "\ebd0" } +.codicon-inspect:before { content: "\ebd1" } +.codicon-layers:before { content: "\ebd2" } +.codicon-layers-dot:before { content: "\ebd3" } +.codicon-layers-active:before { content: "\ebd4" } +.codicon-compass:before { content: "\ebd5" } +.codicon-compass-dot:before { content: "\ebd6" } +.codicon-compass-active:before { content: "\ebd7" } +.codicon-azure:before { content: "\ebd8" } +.codicon-issue-draft:before { content: "\ebd9" } +.codicon-git-pull-request-closed:before { content: "\ebda" } +.codicon-git-pull-request-draft:before { content: "\ebdb" } diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/ui/codicon.ttf b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/ui/codicon.ttf new file mode 100644 index 0000000000000000000000000000000000000000..8d844c9279604c01d015aa1395051fb7e270e420 GIT binary patch literal 65608 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%0D9=G?+pucAU38?H}UL9qt!47 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 IN-TK)Hv!RQ;{X5v literal 0 HcmV?d00001 diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/ui/refactoring.css b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/ui/refactoring.css new file mode 100644 index 000000000000..98c2534bb190 --- /dev/null +++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/refactoring/ui/refactoring.css @@ -0,0 +1,169 @@ + + +html, body { + height: 100%; + padding: 0; + margin: 0; +} +body { + display: flex; + flex-direction: column; + overflow-x: scroll; +} +input, select { + width: 100%; + font-family: var(--vscode-editor-font-family) !important; + border: var(--vscode-input-border); + margin-right: 6px !important; + background: var(--vscode-input-background); + color: var(--vscode-input-foreground); + box-sizing: border-box; +} +input:focus, select:focus { + outline-color: var(--vscode-focusBorder); +} +input { + padding: 5px 4px !important; +} +select { + padding: 4px !important; +} +button { + cursor: pointer; +} +label { + display: block; + margin-bottom: 5px; + user-select: none; +} +.vscode-font { + font-family: var(--vscode-font-family); + font-size: var(--vscode-font-size); + text-decoration: none; +} +.button-text { + margin-left: 5px; + vertical-align: text-top; +} +.regular-button { + border: none; + padding: 4px 10px 4px 10px; + margin: 5px; + color: var(--vscode-button-foreground); + background-color: var(--vscode-button-background); +} +.regular-button:hover, .regular-button:focus { + background: var(--vscode-button-hoverBackground); +} +.regular-button:focus { + outline: 1px solid var(--vscode-button-hoverBackground); + outline-offset: 2px; +} +.silent-button { + border: none; + padding: 4px 10px 4px 10px; + margin: 5px; + color: var(--vscode-input-foreground); + background-color: var(--vscode-list-hoverBackground); +} +.silent-button:hover { + color: var(--vscode-button-foreground); + background-color: var(--vscode-button-hoverBackground); +} +.silent-button:focus { + color: var(--vscode-button-foreground); + background-color: var(--vscode-button-hoverBackground); + outline: 1px solid var(--vscode-button-hoverBackground); + outline-offset: 2px; +} +.action-button { + border: none; + border-radius: 4px; + padding: 2px; + margin: 3px 0px; + color: var(--vscode-input-foreground); + background-color: transparent; +} +.action-button:hover { + background-color: var(--vscode-list-inactiveSelectionBackground); +} +.action-button:focus, .action-button:hover:focus { + color: var(--vscode-button-foreground); + background-color: var(--vscode-button-hoverBackground); + outline: none; +} +.params-caption { + margin-bottom: 8px; +} +.filler { + width: 53px; +} +.preview-panel { + margin: 0px; + padding: 10px; + font-family: var(--vscode-editor-font-family) !important; + background-color: var(--vscode-sideBar-background); + cursor: default; +} +.section { + padding: 20px 20px 0px; +} +.section1 { + padding: 0px 10px; +} +.section2 { + padding: 0px 10px; + margin-top: -6px; +} +.vdivider { + margin-bottom: 20px; +} +.hdivider { + margin-left: 6px; +} +.row { + padding: 3px 10px; +} +.row:hover { + background-color: var(--vscode-list-hoverBackground); +} +.row:focus-within { + background-color: var(--vscode-tab-unfocusedInactiveModifiedBorder); +} +.flex { + display: flex; +} +.flex-grow { + flex-grow: 1; + display: block; +} +.flex-vscrollable { + overflow-x: hidden; + overflow-y: auto; +} +.align-right { + margin-left: auto; +} +.add-param { + padding: 0px 15px; + padding-top: 2px; +} \ No newline at end of file diff --git a/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java b/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java index ade2c83e0b37..7b058bfe8e02 100644 --- a/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java +++ b/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java @@ -147,6 +147,8 @@ import org.netbeans.junit.NbTestCase; import org.netbeans.modules.java.hints.infrastructure.JavaErrorProvider; import org.netbeans.modules.java.lsp.server.TestCodeLanguageClient; +import org.netbeans.modules.java.lsp.server.refactoring.ChangeMethodParameterUI; +import org.netbeans.modules.java.lsp.server.ui.MockHtmlViewer; import org.netbeans.modules.java.source.BootClassPathUtil; import org.netbeans.modules.parsing.impl.indexing.implspi.CacheFolderProvider; import org.netbeans.spi.java.classpath.ClassPathProvider; @@ -4292,6 +4294,8 @@ public CompletableFuture showInputBox(ShowInputBoxParams params) { @Override public CompletableFuture showHtmlPage(HtmlPageParams params) { + ChangeMethodParameterUI ui = MockHtmlViewer.assertDialogShown(params.getUri(), ChangeMethodParameterUI.class); + ui.doRefactoring(); return CompletableFuture.completedFuture(null); } }, client.getInputStream(), client.getOutputStream()); From c316bdbbf798256940f08c1126209ae4513262ec Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Thu, 9 Dec 2021 12:53:18 +0100 Subject: [PATCH 2/4] Documenting the AbstractLspHtmlViewer API and making View visible --- .../org-netbeans-modules-java-lsp-server.sig | 66 ++++++++++++++- .../nbproject/project.properties | 2 +- .../java/lsp/server/htmlui/Buttons.java | 81 +++++++++++++++++++ .../lsp/server/ui/AbstractLspHtmlViewer.java | 69 ++++------------ 4 files changed, 163 insertions(+), 55 deletions(-) create mode 100644 java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/htmlui/Buttons.java diff --git a/java/java.lsp.server/nbproject/org-netbeans-modules-java-lsp-server.sig b/java/java.lsp.server/nbproject/org-netbeans-modules-java-lsp-server.sig index 398d3c2c50ba..6e1607d163c0 100644 --- a/java/java.lsp.server/nbproject/org-netbeans-modules-java-lsp-server.sig +++ b/java/java.lsp.server/nbproject/org-netbeans-modules-java-lsp-server.sig @@ -1,5 +1,5 @@ #Signature file v4.1 -#Version 1.10.0 +#Version 1.14.0 CLSS public java.lang.Object cons public init() @@ -23,6 +23,35 @@ meth public void notifyLater(org.openide.NotifyDescriptor) supr org.openide.DialogDisplayer hfds context +CLSS public org.netbeans.modules.java.lsp.server.ui.AbstractGlobalActionContext +cons public init() +intf org.openide.util.ContextGlobalProvider +intf org.openide.util.Lookup$Provider +meth public org.openide.util.Lookup createGlobalContext() +meth public org.openide.util.Lookup getLookup() +meth public static <%0 extends java.lang.Object> {%%0} withActionContext(org.openide.util.Lookup,java.util.concurrent.Callable<{%%0}>) +supr java.lang.Object +hcls ContextHolder + +CLSS public org.netbeans.modules.java.lsp.server.ui.AbstractLspHtmlViewer +cons protected init() +innr protected final View +intf org.netbeans.spi.htmlui.HTMLViewerSpi +meth public <%0 extends java.lang.Object> {%%0} component(org.netbeans.modules.java.lsp.server.ui.AbstractLspHtmlViewer$View,java.lang.Class<{%%0}>) +meth public java.lang.Object createButton(org.netbeans.modules.java.lsp.server.ui.AbstractLspHtmlViewer$View,java.lang.String) +meth public java.lang.String getId(org.netbeans.modules.java.lsp.server.ui.AbstractLspHtmlViewer$View,java.lang.Object) +meth public org.netbeans.modules.java.lsp.server.ui.AbstractLspHtmlViewer$View newView(org.netbeans.spi.htmlui.HTMLViewerSpi$Context) +meth public void runLater(org.netbeans.modules.java.lsp.server.ui.AbstractLspHtmlViewer$View,java.lang.Runnable) +meth public void setEnabled(org.netbeans.modules.java.lsp.server.ui.AbstractLspHtmlViewer$View,java.lang.Object,boolean) +meth public void setText(org.netbeans.modules.java.lsp.server.ui.AbstractLspHtmlViewer$View,java.lang.Object,java.lang.String) +supr java.lang.Object +hfds initial + +CLSS protected final org.netbeans.modules.java.lsp.server.ui.AbstractLspHtmlViewer$View + outer org.netbeans.modules.java.lsp.server.ui.AbstractLspHtmlViewer +supr java.lang.Object +hfds ctx,presenter,ui + CLSS public abstract org.netbeans.modules.java.lsp.server.ui.AbstractLspInputOutputProvider cons protected init() innr public final static LspIO @@ -92,6 +121,7 @@ meth protected abstract java.util.concurrent.CompletableFuture showHtmlPage(org.netbeans.modules.java.lsp.server.protocol.HtmlPageParams) meth public static org.netbeans.modules.java.lsp.server.ui.UIContext find() anno 0 org.netbeans.api.annotations.common.NonNull() meth public static org.netbeans.modules.java.lsp.server.ui.UIContext find(org.openide.util.Lookup) @@ -104,6 +134,16 @@ CLSS public abstract interface org.netbeans.modules.progress.spi.ProgressEnviron meth public abstract org.netbeans.api.progress.ProgressHandle createHandle(java.lang.String,org.openide.util.Cancellable,boolean) meth public abstract org.netbeans.modules.progress.spi.Controller getController() +CLSS public abstract interface org.netbeans.spi.htmlui.HTMLViewerSpi<%0 extends java.lang.Object, %1 extends java.lang.Object> +innr public final static Context +meth public abstract <%0 extends java.lang.Object> {%%0} component({org.netbeans.spi.htmlui.HTMLViewerSpi%0},java.lang.Class<{%%0}>) +meth public abstract java.lang.String getId({org.netbeans.spi.htmlui.HTMLViewerSpi%0},{org.netbeans.spi.htmlui.HTMLViewerSpi%1}) +meth public abstract void runLater({org.netbeans.spi.htmlui.HTMLViewerSpi%0},java.lang.Runnable) +meth public abstract void setEnabled({org.netbeans.spi.htmlui.HTMLViewerSpi%0},{org.netbeans.spi.htmlui.HTMLViewerSpi%1},boolean) +meth public abstract void setText({org.netbeans.spi.htmlui.HTMLViewerSpi%0},{org.netbeans.spi.htmlui.HTMLViewerSpi%1},java.lang.String) +meth public abstract {org.netbeans.spi.htmlui.HTMLViewerSpi%0} newView(org.netbeans.spi.htmlui.HTMLViewerSpi$Context) +meth public abstract {org.netbeans.spi.htmlui.HTMLViewerSpi%1} createButton({org.netbeans.spi.htmlui.HTMLViewerSpi%0},java.lang.String) + CLSS public abstract interface org.netbeans.spi.io.InputOutputProvider<%0 extends java.lang.Object, %1 extends java.io.PrintWriter, %2 extends java.lang.Object, %3 extends java.lang.Object> meth public abstract boolean isIOClosed({org.netbeans.spi.io.InputOutputProvider%0}) anno 1 org.netbeans.api.annotations.common.NonNull() @@ -190,3 +230,27 @@ supr java.lang.Object hfds INSTANCE hcls Trivial +CLSS public abstract interface org.openide.util.ContextGlobalProvider +meth public abstract org.openide.util.Lookup createGlobalContext() + +CLSS public abstract org.openide.util.Lookup +cons public init() +fld public final static org.openide.util.Lookup EMPTY +innr public abstract interface static Provider +innr public abstract static Item +innr public abstract static Result +innr public final static Template +meth public <%0 extends java.lang.Object> java.util.Collection lookupAll(java.lang.Class<{%%0}>) +meth public <%0 extends java.lang.Object> org.openide.util.Lookup$Item<{%%0}> lookupItem(org.openide.util.Lookup$Template<{%%0}>) +meth public <%0 extends java.lang.Object> org.openide.util.Lookup$Result<{%%0}> lookupResult(java.lang.Class<{%%0}>) +meth public abstract <%0 extends java.lang.Object> org.openide.util.Lookup$Result<{%%0}> lookup(org.openide.util.Lookup$Template<{%%0}>) +meth public abstract <%0 extends java.lang.Object> {%%0} lookup(java.lang.Class<{%%0}>) +meth public static org.openide.util.Lookup getDefault() +supr java.lang.Object +hfds LOG,defaultLookup,defaultLookupProvider +hcls DefLookup,Empty + +CLSS public abstract interface static org.openide.util.Lookup$Provider + outer org.openide.util.Lookup +meth public abstract org.openide.util.Lookup getLookup() + diff --git a/java/java.lsp.server/nbproject/project.properties b/java/java.lsp.server/nbproject/project.properties index 13e2c2cd50ca..2d7c0f38f8e7 100644 --- a/java/java.lsp.server/nbproject/project.properties +++ b/java/java.lsp.server/nbproject/project.properties @@ -17,7 +17,7 @@ javac.source=1.8 javac.compilerargs=-Xlint -Xlint:-serial -spec.version.base=1.13.0 +spec.version.base=1.14.0 requires.nb.javac=true lsp.build.dir=vscode/nbcode test.unit.run.cp.extra= diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/htmlui/Buttons.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/htmlui/Buttons.java new file mode 100644 index 000000000000..c5489918e5eb --- /dev/null +++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/htmlui/Buttons.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.java.lsp.server.htmlui; + +import net.java.html.js.JavaScriptBody; +import org.netbeans.spi.htmlui.HTMLViewerSpi; + +/** + * Helper utilities to deal with HTML buttons. + */ +public final class Buttons { + private Buttons() { + } + + @JavaScriptBody(args = {}, body = "\n" + + "const vscode = acquireVsCodeApi();\n" // this method can be called only once per WebView existance + + "window.close = function() {\n" + + " vscode.postMessage({\n" + + " command: 'dispose',\n" + + " });\n" + + "};\n" + ) + public static native void registerCloseWindow(); + + @JavaScriptBody(args = { "id", "callback" }, javacall = true, body = "\n" + + "var first = false;\n" + + "var footer = document.getElementById('dialog-buttons');\n" + + "if (!footer) {\n" + + " first = true\n" + + " footer = document.createElement('div');\n" + + " footer.id = 'dialog-buttons';\n" + + " footer.classList.add('flex');\n" + + " footer.classList.add('section');\n" + + " document.body.appendChild(footer);\n" + + "}\n" + + "var button = document.createElement('button');\n" + + "button.id = id;\n" + + "button.onclick = function() {;\n" + + " @org.netbeans.modules.java.lsp.server.htmlui.Buttons::clickButton0(Ljava/lang/String;Ljava/lang/Object;)(id, callback);\n" + + "};\n" + + "button.classList.add('regular-button');\n" + + "button.classList.add('vscode-font');\n" + + "if (first) {\n" + + " button.classList.add('align-right');\n" + + "}\n" + + "footer.appendChild(button);\n" + + "return button;\n" + ) + public native static Object createButton0(String id, HTMLViewerSpi.Context callback); + + static void clickButton0(String id, Object callback) { + HTMLViewerSpi.Context ctx = (HTMLViewerSpi.Context) callback; + ctx.onSubmit(id); + } + + @JavaScriptBody(args = { "b" }, body = "return b.id;") + public native static String buttonName0(Object b); + + @JavaScriptBody(args = { "b", "text" }, body = "b.innerHTML = text;") + public native static void buttonText0(Object b, String text); + + @JavaScriptBody(args = { "b", "disabled" }, body = "return b.disabled = disabled;") + public native static String buttonDisabled0(Object b, boolean disabled); + +} diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/ui/AbstractLspHtmlViewer.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/ui/AbstractLspHtmlViewer.java index 02e05b249bb7..10a7d51b4a55 100644 --- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/ui/AbstractLspHtmlViewer.java +++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/ui/AbstractLspHtmlViewer.java @@ -24,13 +24,21 @@ import org.eclipse.lsp4j.MessageType; import org.netbeans.modules.java.lsp.server.htmlui.Browser; import org.netbeans.modules.java.lsp.server.htmlui.Browser.Config; +import org.netbeans.modules.java.lsp.server.htmlui.Buttons; +import static org.netbeans.modules.java.lsp.server.htmlui.Buttons.buttonName0; +import static org.netbeans.modules.java.lsp.server.htmlui.Buttons.buttonText0; import org.netbeans.modules.java.lsp.server.protocol.HtmlPageParams; import org.netbeans.modules.java.lsp.server.protocol.NbCodeClientCapabilities; import org.openide.util.Exceptions; import org.netbeans.spi.htmlui.HTMLViewerSpi; -import org.openide.awt.StatusDisplayer; import org.openide.util.NbBundle; +/** + * Implementation of {@link HTMLViewerSpi} that uses window/showHtmlPage + * extended message of language server protocol to display a page. + * + * @since 1.14 + */ public class AbstractLspHtmlViewer implements HTMLViewerSpi { private final Config initial = new Config(); @@ -44,51 +52,12 @@ public View newView(Context context) { return view; } - @JavaScriptBody(args = {}, body = "\n" - + "const vscode = acquireVsCodeApi();\n" // this method can be called only once per WebView existance - + "window.close = function() {\n" - + " vscode.postMessage({\n" - + " command: 'dispose',\n" - + " });\n" - + "};\n" - ) - private static native void registerCloseWindow(); @Override public Object createButton(View view, String id) { - return createButton0(id, view.ctx); + return Buttons.createButton0(id, view.ctx); } - @JavaScriptBody(args = { "id", "callback" }, javacall = true, body = "\n" - + "var first = false;\n" - + "var footer = document.getElementById('dialog-buttons');\n" - + "if (!footer) {\n" - + " first = true\n" - + " footer = document.createElement('div');\n" - + " footer.id = 'dialog-buttons';\n" - + " footer.classList.add('flex');\n" - + " footer.classList.add('section');\n" - + " document.body.appendChild(footer);\n" - + "}\n" - + "var button = document.createElement('button');\n" - + "button.id = id;\n" - + "button.onclick = function() {;\n" - + " @org.netbeans.modules.java.lsp.server.ui.AbstractLspHtmlViewer::clickButton0(Ljava/lang/String;Ljava/lang/Object;)(id, callback);\n" - + "};\n" - + "button.classList.add('regular-button');\n" - + "button.classList.add('vscode-font');\n" - + "if (first) {\n" - + " button.classList.add('align-right');\n" - + "}\n" - + "footer.appendChild(button);\n" - + "return button;\n" - ) - native static Object createButton0(String id, Context callback); - - static void clickButton0(String id, Object callback) { - Context ctx = (Context) callback; - ctx.onSubmit(id); - } @Override public C component(View view, Class type) { @@ -111,7 +80,7 @@ public void setText(View view, Object b, String text) { @Override public void setEnabled(View view, Object b, boolean enabled) { - buttonDisabled0(b, !enabled); + Buttons.buttonDisabled0(b, !enabled); } @Override @@ -119,16 +88,10 @@ public void runLater(View view, Runnable r) { r.run(); } - @JavaScriptBody(args = { "b" }, body = "return b.id;") - native static String buttonName0(Object b); - - @JavaScriptBody(args = { "b", "text" }, body = "b.innerHTML = text;") - native static void buttonText0(Object b, String text); - - @JavaScriptBody(args = { "b", "disabled" }, body = "return b.disabled = disabled;") - native static String buttonDisabled0(Object b, boolean disabled); - - final class View { + /** View element used by {@link AbstractLspHtmlViewer}. + * @since 1.14 + */ + protected final class View { private final Context ctx; private final UIContext ui; private Browser presenter; @@ -189,7 +152,7 @@ private void load() { }); presenter = new Browser(c); presenter.displayPage(pageUrl, () -> { - registerCloseWindow(); + Buttons.registerCloseWindow(); try { ctx.onPageLoad(); } catch (Exception ex) { From 552c868d41d8de58da557be2337a1148b89cf7ea Mon Sep 17 00:00:00 2001 From: Dusan Balek Date: Thu, 9 Dec 2021 17:16:57 +0100 Subject: [PATCH 3/4] Modified for ServerTest to pass. --- .../lsp/server/ui/AbstractLspHtmlViewer.java | 2 +- .../lsp/server/TestCodeLanguageClient.java | 41 +++++++++++++++---- .../java/lsp/server/protocol/ServerTest.java | 2 + .../java/lsp/server/ui/MockHtmlViewer.java | 15 +++++-- 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/ui/AbstractLspHtmlViewer.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/ui/AbstractLspHtmlViewer.java index 10a7d51b4a55..a1e608787bc4 100644 --- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/ui/AbstractLspHtmlViewer.java +++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/ui/AbstractLspHtmlViewer.java @@ -92,7 +92,7 @@ public void runLater(View view, Runnable r) { * @since 1.14 */ protected final class View { - private final Context ctx; + final Context ctx; private final UIContext ui; private Browser presenter; diff --git a/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/TestCodeLanguageClient.java b/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/TestCodeLanguageClient.java index 7b1745f7214b..607f9f63e9fe 100644 --- a/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/TestCodeLanguageClient.java +++ b/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/TestCodeLanguageClient.java @@ -18,12 +18,19 @@ */ package org.netbeans.modules.java.lsp.server; +import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; +import org.eclipse.lsp4j.ApplyWorkspaceEditParams; +import org.eclipse.lsp4j.ApplyWorkspaceEditResponse; +import org.eclipse.lsp4j.ConfigurationParams; import org.eclipse.lsp4j.MessageActionItem; import org.eclipse.lsp4j.MessageParams; +import org.eclipse.lsp4j.ProgressParams; import org.eclipse.lsp4j.PublishDiagnosticsParams; import org.eclipse.lsp4j.ShowMessageRequestParams; +import org.eclipse.lsp4j.WorkDoneProgressCreateParams; import org.netbeans.modules.java.lsp.server.explorer.api.NodeChangedParams; import org.netbeans.modules.java.lsp.server.protocol.DecorationRenderOptions; import org.netbeans.modules.java.lsp.server.protocol.HtmlPageParams; @@ -37,6 +44,26 @@ import org.netbeans.modules.java.lsp.server.protocol.TestProgressParams; public abstract class TestCodeLanguageClient implements NbCodeLanguageClient { + + @Override + public CompletableFuture createProgress(WorkDoneProgressCreateParams params) { + return CompletableFuture.completedFuture(null); + } + + @Override + public void notifyProgress(ProgressParams params) { + } + + @Override + public CompletableFuture applyEdit(ApplyWorkspaceEditParams params) { + throw new UnsupportedOperationException(); + } + + @Override + public CompletableFuture> configuration(ConfigurationParams params) { + return CompletableFuture.completedFuture(Collections.emptyList()); + } + @Override public void showStatusBarMessage(ShowStatusMessageParams params) { throw new UnsupportedOperationException(); @@ -49,7 +76,7 @@ public CompletableFuture showHtmlPage(HtmlPageParams params) { @Override public CompletableFuture> showQuickPick(ShowQuickPickParams params) { - throw new UnsupportedOperationException(); + return CompletableFuture.completedFuture(params.getItems().stream().filter(item -> item.isPicked()).collect(Collectors.toList())); } @Override @@ -83,27 +110,25 @@ public NbCodeClientCapabilities getNbCodeCapabilities() { } @Override - public void telemetryEvent(Object arg0) { + public void telemetryEvent(Object params) { throw new UnsupportedOperationException(); } @Override - public void publishDiagnostics(PublishDiagnosticsParams arg0) { - throw new UnsupportedOperationException(); + public void publishDiagnostics(PublishDiagnosticsParams params) { } @Override - public void showMessage(MessageParams arg0) { - throw new UnsupportedOperationException(); + public void showMessage(MessageParams params) { } @Override - public CompletableFuture showMessageRequest(ShowMessageRequestParams arg0) { + public CompletableFuture showMessageRequest(ShowMessageRequestParams params) { throw new UnsupportedOperationException(); } @Override - public void logMessage(MessageParams arg0) { + public void logMessage(MessageParams params) { throw new UnsupportedOperationException(); } diff --git a/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java b/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java index 7b058bfe8e02..a95ff42476af 100644 --- a/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java +++ b/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java @@ -148,6 +148,7 @@ import org.netbeans.modules.java.hints.infrastructure.JavaErrorProvider; import org.netbeans.modules.java.lsp.server.TestCodeLanguageClient; import org.netbeans.modules.java.lsp.server.refactoring.ChangeMethodParameterUI; +import org.netbeans.modules.java.lsp.server.refactoring.ParameterUI; import org.netbeans.modules.java.lsp.server.ui.MockHtmlViewer; import org.netbeans.modules.java.source.BootClassPathUtil; import org.netbeans.modules.parsing.impl.indexing.implspi.CacheFolderProvider; @@ -4295,6 +4296,7 @@ public CompletableFuture showInputBox(ShowInputBoxParams params) { @Override public CompletableFuture showHtmlPage(HtmlPageParams params) { ChangeMethodParameterUI ui = MockHtmlViewer.assertDialogShown(params.getUri(), ChangeMethodParameterUI.class); + ui.getParameters().add(1, new ParameterUI("int", "cnt")); ui.doRefactoring(); return CompletableFuture.completedFuture(null); } diff --git a/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/ui/MockHtmlViewer.java b/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/ui/MockHtmlViewer.java index ec1ed3d06f58..246686416dc0 100644 --- a/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/ui/MockHtmlViewer.java +++ b/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/ui/MockHtmlViewer.java @@ -44,11 +44,10 @@ public final class MockHtmlViewer extends AbstractLspHtmlViewer { @Override public View newView(Context ctx) { View v = super.newView(ctx); - load(v, ctx.getClassLoader(), ctx.getPage(), ctx::onPageLoad, ctx.getTechIds()); return v; } - private void load(View view, ClassLoader loader, URL pageUrl, Callable initialize, String[] techIds) { + private void load(View view) { UIContext ui = UIContext.find(); String key = UUID.randomUUID().toString(); @@ -56,7 +55,7 @@ private void load(View view, ClassLoader loader, URL pageUrl, Callable i ctx.execute(() -> { Object v; try (Closeable c = Fn.activate(Contexts.find(ctx, Fn.Presenter.class))) { - v = initialize.call(); + v = view.ctx.onPageLoad(); } catch (Exception ex) { MockTech.exception(ctx, ex); } @@ -74,6 +73,15 @@ public static T assertDialogShown(String uri, Class clazz) { return clazz.cast(v); } + @Override + public C component(View view, Class type) { + if (type == Void.class) { + load(view); + return null; + } + throw new ClassCastException(); + } + private BrwsrCtx mockPresenter() { final Fn.Presenter p = new Fn.Presenter() { @Override @@ -134,7 +142,6 @@ public void bind(PropertyBinding pb, Object o, Object data) { @Override public void valueHasMutated(Object data, String string) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override From 22dd80e15c7879bb17a15bf7f32da3df39b8c5b5 Mon Sep 17 00:00:00 2001 From: Dusan Balek Date: Thu, 9 Dec 2021 17:29:18 +0100 Subject: [PATCH 4/4] Cleanup. --- .../modules/java/lsp/server/ui/MockHtmlViewer.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/ui/MockHtmlViewer.java b/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/ui/MockHtmlViewer.java index 246686416dc0..1d10a3c47e75 100644 --- a/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/ui/MockHtmlViewer.java +++ b/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/ui/MockHtmlViewer.java @@ -25,7 +25,6 @@ import java.util.HashMap; import java.util.Map; import java.util.UUID; -import java.util.concurrent.Callable; import net.java.html.BrwsrCtx; import static org.junit.Assert.assertTrue; import org.netbeans.html.boot.spi.Fn; @@ -41,12 +40,6 @@ public final class MockHtmlViewer extends AbstractLspHtmlViewer { private static final Map data = Collections.synchronizedMap(new HashMap<>()); - @Override - public View newView(Context ctx) { - View v = super.newView(ctx); - return v; - } - private void load(View view) { UIContext ui = UIContext.find(); String key = UUID.randomUUID().toString();