diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/codeactions/ExtractStructureConstructorSupplier.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/codeactions/ExtractStructureConstructorSupplier.java index 04de6cfa0b1..0b437c6fd88 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/codeactions/ExtractStructureConstructorSupplier.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/codeactions/ExtractStructureConstructorSupplier.java @@ -32,6 +32,7 @@ import com.github._1c_syntax.bsl.parser.BSLParser; import com.github._1c_syntax.bsl.parser.BSLParserRuleContext; import lombok.RequiredArgsConstructor; +import org.antlr.v4.runtime.RuleContext; import org.antlr.v4.runtime.tree.TerminalNode; import org.eclipse.lsp4j.CodeAction; import org.eclipse.lsp4j.CodeActionKind; @@ -101,11 +102,11 @@ public List getCodeActions(CodeActionParams params, DocumentContext } var assignment = (BSLParser.AssignmentContext) Trees.getAncestorByRuleIndex(doCall, BSLParser.RULE_assignment); - if (assignment == null) { + if (assignment == null || isParentAssignment(doCall, assignment)) { return Collections.emptyList(); } - var lValue = assignment.lValue().IDENTIFIER(); + var lValue = assignment.lValue(); if (lValue == null) { return Collections.emptyList(); } @@ -147,11 +148,19 @@ public List getCodeActions(CodeActionParams params, DocumentContext var codeAction = new CodeAction(); codeAction.setEdit(workspaceEdit); - codeAction.setKind(CodeActionKind.RefactorExtract); + codeAction.setKind(CodeActionKind.Refactor); codeAction.setIsPreferred(Boolean.TRUE); codeAction.setTitle(Resources.getResourceString(configuration.getLanguage(), getClass(), "title")); return Collections.singletonList(codeAction); } + + private static boolean isParentAssignment(BSLParser.DoCallContext doCall, BSLParser.AssignmentContext assignment) { + return assignment.expression().member().stream() + .map(BSLParser.MemberContext::complexIdentifier) + .map(BSLParser.ComplexIdentifierContext::newExpression) + .filter(newExpressionContext -> newExpressionContext == doCall.getParent()) + .findAny().isEmpty(); + } } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/codeactions/ExtractStructureConstructorSupplierTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/codeactions/ExtractStructureConstructorSupplierTest.java index fb865b12900..c44ac2397e2 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/codeactions/ExtractStructureConstructorSupplierTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/codeactions/ExtractStructureConstructorSupplierTest.java @@ -23,13 +23,16 @@ import com.github._1c_syntax.bsl.languageserver.configuration.Language; import com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration; +import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; import com.github._1c_syntax.bsl.languageserver.util.TestUtils; import com.github._1c_syntax.bsl.languageserver.utils.Ranges; import org.eclipse.lsp4j.CodeAction; import org.eclipse.lsp4j.CodeActionContext; import org.eclipse.lsp4j.CodeActionParams; import org.eclipse.lsp4j.Diagnostic; +import org.eclipse.lsp4j.Range; import org.eclipse.lsp4j.TextDocumentIdentifier; +import org.eclipse.lsp4j.TextEdit; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -42,21 +45,151 @@ @SpringBootTest class ExtractStructureConstructorSupplierTest { - @Autowired private LanguageServerConfiguration configuration; @Autowired private ExtractStructureConstructorSupplier codeActionSupplier; + private DocumentContext documentContext; + private CodeActionParams params; @Test void testGetCodeActions() { // given + setRange(Ranges.create(1, 21, 23)); + + // when + List codeActions = codeActionSupplier.getCodeActions(params, documentContext); + + assertThat(codeActions) + .hasSize(1) + .anyMatch(codeAction -> codeAction.getTitle().equals("Unwrap constructor")); + + assertThat((((ArrayList) (codeActions.get(0).getEdit().getChanges().values()).toArray()[0]))) + .hasSize(4) + .anyMatch(textedit -> ((TextEdit) textedit).getNewText().equals("()")) + .anyMatch(textedit -> ((TextEdit) textedit).getNewText().equals("Структура.Insert(\"а\", а);\n")) + .anyMatch(textedit -> ((TextEdit) textedit).getNewText().equals("Структура.Insert(\"б\", б);\n")) + .anyMatch(textedit -> ((TextEdit) textedit).getNewText().equals("Структура.Insert(\"в\", в);\n")) + ; + } + + @Test + void testGetCodeActionsDouble() { + + // given + setRange(Ranges.create(6, 14, 17)); + + // when + List codeActions = codeActionSupplier.getCodeActions(params, documentContext); + + assertThat(codeActions) + .hasSize(0) + .noneMatch(codeAction -> codeAction.getTitle().equals("Unwrap constructor")); + } + + @Test + void testGetCodeActionsFind() { + + // given + setRange(Ranges.create(10, 76, 78)); + + // when + List codeActions = codeActionSupplier.getCodeActions(params, documentContext); + + assertThat(codeActions) + .hasSize(0) + .noneMatch(codeAction -> codeAction.getTitle().equals("Unwrap constructor")); + } + + @Test + void testGetCodeActionsArray() { + + // given + setRange(Ranges.create(12, 21, 23)); + + // when + List codeActions = codeActionSupplier.getCodeActions(params, documentContext); + + assertThat(codeActions) + .hasSize(0) + .noneMatch(codeAction -> codeAction.getTitle().equals("Unwrap constructor")); + + } + + @Test + void testGetCodeActionsNOParams() { + + // given + setRange(Ranges.create(14, 21, 23)); + + // when + List codeActions = codeActionSupplier.getCodeActions(params, documentContext); + + assertThat(codeActions) + .hasSize(0) + .noneMatch(codeAction -> codeAction.getTitle().equals("Unwrap constructor")); + + } + + @Test + void testGetCodeActionsEmptyParams() { + + // given + setRange(Ranges.create(14, 21, 23)); + + // when + List codeActions = codeActionSupplier.getCodeActions(params, documentContext); + + assertThat(codeActions) + .hasSize(0) + .noneMatch(codeAction -> codeAction.getTitle().equals("Unwrap constructor")); + + } + + @Test + void testGetCodeActionsIdentifier() { + + // given + setRange(Ranges.create(15, 21, 23)); + + // when + List codeActions = codeActionSupplier.getCodeActions(params, documentContext); + + assertThat(codeActions) + .hasSize(0) + .noneMatch(codeAction -> codeAction.getTitle().equals("Unwrap constructor")); + + } + + @Test + void testGetCodeActionsObject() { + + // given + setRange(Ranges.create(17, 21, 23)); + + // when + List codeActions = codeActionSupplier.getCodeActions(params, documentContext); + + assertThat(codeActions) + .hasSize(1) + .anyMatch(codeAction -> codeAction.getTitle().equals("Unwrap constructor")); + assertThat((((ArrayList) (codeActions.get(0).getEdit().getChanges().values()).toArray()[0]))) + .hasSize(4) + .anyMatch(textedit -> ((TextEdit) textedit).getNewText().equals("()")) + .anyMatch(textedit -> ((TextEdit) textedit).getNewText().equals("Чтото.Поле.Insert(\"а\", а);\n")) + .anyMatch(textedit -> ((TextEdit) textedit).getNewText().equals("Чтото.Поле.Insert(\"б\", б);\n")) + .anyMatch(textedit -> ((TextEdit) textedit).getNewText().equals("Чтото.Поле.Insert(\"в\", в);\n")) + ; + + } + + void setRange(Range range) { configuration.setLanguage(Language.EN); String filePath = "./src/test/resources/suppliers/extractStructureConstructor.bsl"; - var documentContext = TestUtils.getDocumentContextFromFile(filePath); + documentContext = TestUtils.getDocumentContextFromFile(filePath); List diagnostics = new ArrayList<>(); @@ -65,20 +198,10 @@ void testGetCodeActions() { CodeActionContext codeActionContext = new CodeActionContext(); codeActionContext.setDiagnostics(diagnostics); - CodeActionParams params = new CodeActionParams(); - params.setRange(Ranges.create(1, 21, 23)); + params = new CodeActionParams(); + params.setRange(range); params.setTextDocument(textDocumentIdentifier); params.setContext(codeActionContext); - - // when - List codeActions = codeActionSupplier.getCodeActions(params, documentContext); - - assertThat(codeActions) - .hasSize(1) - .anyMatch(codeAction -> codeAction.getTitle().equals("Generate missing regions")); } - @Test - void getCodeActions() { - } } \ No newline at end of file diff --git a/src/test/resources/suppliers/extractStructureConstructor.bsl b/src/test/resources/suppliers/extractStructureConstructor.bsl index c1c1da486cd..31ed8f64068 100644 --- a/src/test/resources/suppliers/extractStructureConstructor.bsl +++ b/src/test/resources/suppliers/extractStructureConstructor.bsl @@ -2,3 +2,17 @@ Структура = Новый Структура("а, б, в", а, б, в); Структура = Новый Структура("а, б, в", а, б, в); + +СтруктураПолей = Новый Структура("Измерения, Реквизиты, Ресурсы", + Новый Структура("СтрокаПолей", ""), + Новый Структура("СтрокаПолей", ""), + Новый Структура("СтрокаПолей", "")); + +СтрокиВопроса = СтрокаДерева.СоставКомплексногоВопроса.НайтиСтроки(Новый Структура("ЭлементарныйВопрос", ВыборкаВопрос.ЭлементарныйВопрос)); + +Структура = Новый Массив(); +Структура = Новый Структура; +Структура = Новый Структура(); +Структура = Новый Структура(Идентификатор); + +Чтото.Поле = Новый Структура("а, б, в", а, б, в);