diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLLanguageServer.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLLanguageServer.java index 2be3d0562e6..2e4608ea2b7 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLLanguageServer.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLLanguageServer.java @@ -94,7 +94,7 @@ public class BSLLanguageServer implements LanguageServer, ProtocolExtension { public CompletableFuture initialize(InitializeParams params) { clientCapabilitiesHolder.setCapabilities(params.getCapabilities()); - + setConfigurationRoot(params); var factory = new NamedForkJoinWorkerThreadFactory("populate-context-"); diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLWorkspaceService.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLWorkspaceService.java index 0cdf596d6c8..96f8e91fe24 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLWorkspaceService.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLWorkspaceService.java @@ -60,7 +60,7 @@ private void onDestroy() { } @Override - public CompletableFuture,List>> symbol(WorkspaceSymbolParams params) { + public CompletableFuture, List>> symbol(WorkspaceSymbolParams params) { return CompletableFuture.supplyAsync( () -> Either.forRight(symbolProvider.getSymbols(params)), executorService diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/cfg/BasicBlockVertex.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/cfg/BasicBlockVertex.java index 1c28ce385bf..d718f3bcb81 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/cfg/BasicBlockVertex.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/cfg/BasicBlockVertex.java @@ -41,7 +41,7 @@ public void addStatement(BSLParserRuleContext statement) { @Override public Optional getAst() { - if(statements.isEmpty()) { + if (statements.isEmpty()) { return super.getAst(); } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/cfg/ControlFlowGraphWalker.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/cfg/ControlFlowGraphWalker.java index feda24b33d2..ae04ff63008 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/cfg/ControlFlowGraphWalker.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/cfg/ControlFlowGraphWalker.java @@ -60,7 +60,7 @@ public CfgEdge walkNext(CfgEdgeType edgeType) { .filter(x -> x.getType() == edgeType) .findAny(); - if(edgeOrNot.isPresent()) { + if (edgeOrNot.isPresent()) { currentNode = graph.getEdgeTarget(edgeOrNot.get()); return edgeOrNot.get(); } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/cli/FormatCommand.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/cli/FormatCommand.java index 9be7ea72071..2b9deb7637d 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/cli/FormatCommand.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/cli/FormatCommand.java @@ -134,7 +134,7 @@ private List findFilesForFormatting(String[] filePaths) { continue; } - if(srcDir.toFile().isDirectory()) { + if (srcDir.toFile().isDirectory()) { files.addAll(FileUtils.listFiles(srcDir.toFile(), new String[]{"bsl", "os"}, true)); } else { files.add(srcDir.toFile()); diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/codeactions/DisableDiagnosticTriggeringSupplier.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/codeactions/DisableDiagnosticTriggeringSupplier.java index 723dbad7c4f..3bde89d71f9 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/codeactions/DisableDiagnosticTriggeringSupplier.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/codeactions/DisableDiagnosticTriggeringSupplier.java @@ -46,7 +46,6 @@ import static com.github._1c_syntax.bsl.languageserver.providers.DiagnosticProvider.SOURCE; - @Component public class DisableDiagnosticTriggeringSupplier implements CodeActionSupplier { @@ -83,14 +82,14 @@ public List getCodeActions(CodeActionParams params, DocumentContext .stream() .filter(token -> token.getLine() == selectedLineNumber) .max(Comparator.comparingInt(Token::getCharPositionInLine)) - .ifPresent(token -> { - if (params.getRange().getStart().getLine() == params.getRange().getEnd().getLine()) { - result.addAll(getDisableActionForLine(params, documentContext, token)); - } else { - result.addAll(getDisableActionForRange(params, documentContext, token)); + .ifPresent((Token token) -> { + if (params.getRange().getStart().getLine() == params.getRange().getEnd().getLine()) { + result.addAll(getDisableActionForLine(params, documentContext, token)); + } else { + result.addAll(getDisableActionForRange(params, documentContext, token)); + } } - } - ); + ); } result.addAll( @@ -176,13 +175,13 @@ private List actionDisableDiagnostic(Function fu private List createInRegionTextEdits(String diagnosticName, Token last, CodeActionParams params) { List edits = new ArrayList<>(); - Range disableRange = Ranges.create( + var disableRange = Ranges.create( params.getRange().getStart().getLine(), 0, params.getRange().getStart().getLine(), 0 ); - TextEdit disableTextEdit = new TextEdit(disableRange, String.format("// BSLLS%s-off%n", diagnosticName)); + var disableTextEdit = new TextEdit(disableRange, String.format("// BSLLS%s-off%n", diagnosticName)); edits.add(disableTextEdit); Range enableRange = Ranges.create( @@ -191,13 +190,13 @@ private List createInRegionTextEdits(String diagnosticName, Token last params.getRange().getEnd().getLine(), last.getCharPositionInLine() + last.getText().length() ); - TextEdit enableTextEdit = new TextEdit(enableRange, String.format("%n// BSLLS%s-on%n", diagnosticName)); + var enableTextEdit = new TextEdit(enableRange, String.format("%n// BSLLS%s-on%n", diagnosticName)); edits.add(enableTextEdit); return edits; } private List createInFileTextEdits(String diagnosticName) { - TextEdit textEdit = new TextEdit( + var textEdit = new TextEdit( Ranges.create(0, 0, 0, 0), String.format("// BSLLS%s-off%n", diagnosticName) ); @@ -206,10 +205,10 @@ private List createInFileTextEdits(String diagnosticName) { private CodeAction createCodeAction(String title, List edits, DocumentContext documentContext) { Map> changes = Map.of(documentContext.getUri().toString(), edits); - WorkspaceEdit edit = new WorkspaceEdit(); + var edit = new WorkspaceEdit(); edit.setChanges(changes); - CodeAction codeAction = new CodeAction(title); + var codeAction = new CodeAction(title); codeAction.setDiagnostics(new ArrayList<>()); codeAction.setKind(CodeActionKind.Refactor); codeAction.setEdit(edit); @@ -225,15 +224,14 @@ private String getMessage(String key, Object... args) { } private static List createInLineTextEdits(String diagnosticName, Token last, CodeActionParams params) { - Range range = Ranges.create( + var range = Ranges.create( params.getRange().getStart().getLine(), last.getCharPositionInLine() + last.getText().length(), params.getRange().getStart().getLine(), last.getCharPositionInLine() + last.getText().length() ); - TextEdit textEdit = new TextEdit(range, String.format(" // BSLLS%s-off", diagnosticName)); + var textEdit = new TextEdit(range, String.format(" // BSLLS%s-off", diagnosticName)); return Collections.singletonList(textEdit); } - } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/codeactions/QuickFixSupplier.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/codeactions/QuickFixSupplier.java index f1cdcf3a836..e987d1b4e43 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/codeactions/QuickFixSupplier.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/codeactions/QuickFixSupplier.java @@ -49,8 +49,8 @@ public > Optional (Class) aClass); diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/databind/ParametersDeserializer.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/databind/ParametersDeserializer.java index 8f94f39cbb6..1745e43f91e 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/databind/ParametersDeserializer.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/databind/ParametersDeserializer.java @@ -78,7 +78,8 @@ private static Map getParameterConfiguration( ) { Map parameterConfiguration; try { - JavaType type = mapper.getTypeFactory().constructType(new TypeReference>() {}); + JavaType type = mapper.getTypeFactory().constructType(new TypeReference>() { + }); parameterConfiguration = mapper.readValue(mapper.treeAsTokens(parameterConfig), type); } catch (IOException e) { LOGGER.error("Can't deserialize parameter configuration", e); diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContext.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContext.java index ab853043114..430b97a4096 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContext.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContext.java @@ -28,6 +28,7 @@ import com.github._1c_syntax.bsl.languageserver.context.computer.CyclomaticComplexityComputer; import com.github._1c_syntax.bsl.languageserver.context.computer.DiagnosticComputer; import com.github._1c_syntax.bsl.languageserver.context.computer.DiagnosticIgnoranceComputer; +import com.github._1c_syntax.bsl.languageserver.context.computer.ModuleTypeComputer; import com.github._1c_syntax.bsl.languageserver.context.computer.QueryComputer; import com.github._1c_syntax.bsl.languageserver.context.computer.SymbolTreeComputer; import com.github._1c_syntax.bsl.languageserver.context.symbol.MethodSymbol; @@ -70,7 +71,6 @@ import java.util.Optional; import java.util.concurrent.locks.ReentrantLock; import java.util.regex.Pattern; -import java.util.stream.Collectors; import static java.util.Objects.requireNonNull; import static org.antlr.v4.runtime.Token.DEFAULT_CHANNEL; @@ -118,6 +118,7 @@ public class DocumentContext { private final Lazy contentList = new Lazy<>(this::computeContentList, computeLock); private final Lazy moduleType = new Lazy<>(this::computeModuleType, computeLock); + private final Lazy typeName = new Lazy<>(this::computeTypeName, computeLock); private final Lazy cognitiveComplexityData = new Lazy<>(this::computeCognitiveComplexity, computeLock); private final Lazy cyclomaticComplexityData @@ -158,13 +159,13 @@ public List getTokens() { } public List getTokensFromDefaultChannel() { - return getTokens().stream().filter(token -> token.getChannel() == DEFAULT_CHANNEL).collect(Collectors.toList()); + return getTokens().stream().filter(token -> token.getChannel() == DEFAULT_CHANNEL).toList(); } public List getComments() { return getTokens().stream() .filter(token -> token.getType() == BSLLexer.LINE_COMMENT) - .collect(Collectors.toList()); + .toList(); } public String getText(Range range) { @@ -236,6 +237,10 @@ public ModuleType getModuleType() { return moduleType.getOrCompute(); } + public String getTypeName() { + return typeName.getOrCompute(); + } + public SupportVariant getSupportVariant() { return getMdObject().map(MD::getSupportVariant).orElse(SupportVariant.NONE); } @@ -363,9 +368,14 @@ private SymbolTree computeSymbolTree() { return new SymbolTreeComputer(this).compute(); } - private ModuleType computeModuleType() { - return context.getConfiguration().getModuleTypeByURI(uri); + + return new ModuleTypeComputer(this).computeModuleType(); + } + + private String computeTypeName() { + + return new ModuleTypeComputer(this).computeTypeName(); } private ComplexityData computeCognitiveComplexity() { diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentState.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentState.java new file mode 100644 index 00000000000..e6af4827983 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentState.java @@ -0,0 +1,36 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright (c) 2018-2024 + * Alexey Sosnoviy , Nikita Fedkin and contributors + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * BSL Language Server is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * BSL Language Server is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with BSL Language Server. + */ +package com.github._1c_syntax.bsl.languageserver.context; + +/** + * Состояние документа в контексте. + */ +public enum DocumentState { + /** + * В документе отсутствует контент или он был очищен. + */ + WITHOUT_CONTENT, + /** + * В документе присутствует контент. + */ + WITH_CONTENT +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/ServerContext.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/ServerContext.java index 9835fc5cb1e..2f925a20637 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/ServerContext.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/ServerContext.java @@ -73,7 +73,7 @@ public class ServerContext { = Collections.synchronizedMap(new HashMap<>()); private final ReadWriteLock contextLock = new ReentrantReadWriteLock(); - private final Map states = new ConcurrentHashMap<>(); + private final Map states = new ConcurrentHashMap<>(); private final Set openedDocuments = ConcurrentHashMap.newKeySet(); public void populateContext() { @@ -214,12 +214,12 @@ public void openDocument(DocumentContext documentContext, String content, Intege * @param documentContext документ, который необходимо перестроить. */ public void rebuildDocument(DocumentContext documentContext) { - if (states.get(documentContext) == State.WITH_CONTENT) { + if (states.get(documentContext) == DocumentState.WITH_CONTENT) { return; } documentContext.rebuild(); - states.put(documentContext, State.WITH_CONTENT); + states.put(documentContext, DocumentState.WITH_CONTENT); } /** @@ -231,7 +231,11 @@ public void rebuildDocument(DocumentContext documentContext) { */ public void rebuildDocument(DocumentContext documentContext, String content, Integer version) { documentContext.rebuild(content, version); - states.put(documentContext, State.WITH_CONTENT); + states.put(documentContext, DocumentState.WITH_CONTENT); + } + + public DocumentState getDocumentState(DocumentContext documentContext) { + return states.get(documentContext); } /** @@ -244,7 +248,7 @@ public void tryClearDocument(DocumentContext documentContext) { return; } - states.put(documentContext, State.WITHOUT_CONTENT); + states.put(documentContext, DocumentState.WITHOUT_CONTENT); documentContext.clearSecondaryData(); } @@ -255,7 +259,7 @@ public void tryClearDocument(DocumentContext documentContext) { */ public void closeDocument(DocumentContext documentContext) { openedDocuments.remove(documentContext); - states.put(documentContext, State.WITHOUT_CONTENT); + states.put(documentContext, DocumentState.WITHOUT_CONTENT); documentContext.clearSecondaryData(); } @@ -332,18 +336,4 @@ private String getMessage(String key) { return Resources.getResourceString(languageServerConfiguration.getLanguage(), getClass(), key); } - /** - * Состояние документа в контексте. - */ - private enum State { - /** - * В документе отсутствует контент или он был очищен. - */ - WITHOUT_CONTENT, - /** - * В документе присутствует контент. - */ - WITH_CONTENT - } - } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/computer/ModuleTypeComputer.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/computer/ModuleTypeComputer.java new file mode 100644 index 00000000000..7f460645a2b --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/computer/ModuleTypeComputer.java @@ -0,0 +1,76 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright (c) 2018-2024 + * Alexey Sosnoviy , Nikita Fedkin and contributors + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * BSL Language Server is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * BSL Language Server is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with BSL Language Server. + */ +package com.github._1c_syntax.bsl.languageserver.context.computer; + +import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; +import com.github._1c_syntax.bsl.languageserver.context.FileType; +import com.github._1c_syntax.bsl.types.ModuleType; + +import java.nio.file.Path; + +public class ModuleTypeComputer { + + private final DocumentContext documentContext; + + public ModuleTypeComputer(DocumentContext documentContext) { + this.documentContext = documentContext; + } + + public ModuleType computeModuleType() { + + ModuleType moduleType; + if (documentContext.getFileType() == FileType.BSL) { + moduleType = computeBSL(); + } else if (documentContext.getFileType() == FileType.OS) { + moduleType = computeOS(); + } else { + moduleType = ModuleType.UNKNOWN; + } + + return moduleType; + } + + private ModuleType computeBSL() { + var type = documentContext.getServerContext() + .getConfiguration().getModuleTypeByURI(documentContext.getUri()); + return ModuleType.valueOf(type.name()); + } + + private ModuleType computeOS() { + if (documentContext.getUri().getPath().contains("Модули")) { + return ModuleType.OScriptModule; + } else if (documentContext.getUri().getPath().contains("Классы")) { + return ModuleType.OScriptClass; + } else { + return ModuleType.UNKNOWN; + } + } + + public String computeTypeName() { + if (documentContext.getModuleType() == ModuleType.OScriptModule + || documentContext.getModuleType() == ModuleType.OScriptClass) { + return Path.of(documentContext.getUri()).getFileName().toString().replace(".os", ""); + } + return ""; + } +} + diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/computer/VariableSymbolComputer.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/computer/VariableSymbolComputer.java index e902d03b770..5334385eb77 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/computer/VariableSymbolComputer.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/computer/VariableSymbolComputer.java @@ -30,6 +30,7 @@ import com.github._1c_syntax.bsl.languageserver.context.symbol.variable.VariableKind; import com.github._1c_syntax.bsl.languageserver.utils.Ranges; import com.github._1c_syntax.bsl.languageserver.utils.Trees; +import com.github._1c_syntax.bsl.languageserver.utils.bsl.Constructors; import com.github._1c_syntax.bsl.parser.BSLParser; import com.github._1c_syntax.bsl.parser.BSLParserBaseVisitor; import com.github._1c_syntax.bsl.parser.BSLParserRuleContext; @@ -62,7 +63,7 @@ public class VariableSymbolComputer extends BSLParserBaseVisitor impl private SourceDefinedSymbol currentMethod; - public VariableSymbolComputer(DocumentContext documentContext, ModuleSymbol module, List methods) { + public VariableSymbolComputer(DocumentContext documentContext, ModuleSymbol module, List methods) { this.documentContext = documentContext; this.module = module; this.methods = methods.stream().collect(toMap(MethodSymbol::getSubNameRange, Function.identity())); @@ -156,16 +157,19 @@ public ParseTree visitParam(BSLParser.ParamContext ctx) { } @Override - public ParseTree visitLValue(BSLParser.LValueContext ctx) { + public ParseTree visitAssignment(BSLParser.AssignmentContext ctx) { + + var lValue = ctx.lValue(); + if ( - ctx.getChildCount() > 1 - || currentMethodVariables.containsKey(ctx.getText()) - || moduleVariables.containsKey(ctx.getText()) + lValue.getChildCount() > 1 + || currentMethodVariables.containsKey(lValue.getText()) + || moduleVariables.containsKey(lValue.getText()) ) { - return ctx; + return lValue; } - updateVariablesCache(ctx.IDENTIFIER(), createDescription(ctx)); + updateVariablesCache(lValue.IDENTIFIER(), createDescription(lValue), typeName(ctx)); return ctx; } @@ -173,7 +177,7 @@ public ParseTree visitLValue(BSLParser.LValueContext ctx) { public ParseTree visitForStatement(BSLParser.ForStatementContext ctx) { if ( currentMethodVariables.containsKey(ctx.IDENTIFIER().getText()) - || moduleVariables.containsKey(ctx.IDENTIFIER().getText()) + || moduleVariables.containsKey(ctx.IDENTIFIER().getText()) ) { return super.visitForStatement(ctx); } @@ -186,7 +190,7 @@ public ParseTree visitForStatement(BSLParser.ForStatementContext ctx) { public ParseTree visitForEachStatement(BSLParser.ForEachStatementContext ctx) { if ( currentMethodVariables.containsKey(ctx.IDENTIFIER().getText()) - || moduleVariables.containsKey(ctx.IDENTIFIER().getText()) + || moduleVariables.containsKey(ctx.IDENTIFIER().getText()) ) { return super.visitForEachStatement(ctx); } @@ -205,16 +209,16 @@ private SourceDefinedSymbol getVariableScope(BSLParser.SubVarDeclarationContext } private SourceDefinedSymbol getVariableScope(BSLParser.SubContext ctx) { - BSLParserRuleContext subNameNode; - if (Trees.nodeContainsErrors(ctx)) { - return module; - } else if (ctx.function() != null) { - subNameNode = ctx.function().funcDeclaration().subName(); - } else { - subNameNode = ctx.procedure().procDeclaration().subName(); - } - - return methods.getOrDefault(Ranges.create(subNameNode), module); + BSLParserRuleContext subNameNode; + if (Trees.nodeContainsErrors(ctx)) { + return module; + } else if (ctx.function() != null) { + subNameNode = ctx.function().funcDeclaration().subName(); + } else { + subNameNode = ctx.procedure().procDeclaration().subName(); + } + + return methods.getOrDefault(Ranges.create(subNameNode), module); } private Optional createDescription(BSLParser.LValueContext ctx) { @@ -249,7 +253,11 @@ private Optional createDescription(BSLParserRuleContext ctx } - private void updateVariablesCache(TerminalNode node, Optional description) { + private void updateVariablesCache(TerminalNode identifier, Optional description) { + updateVariablesCache(identifier, description, ""); + } + + private void updateVariablesCache(TerminalNode node, Optional description, String type) { var variable = VariableSymbol.builder() .name(node.getText().intern()) .owner(documentContext) @@ -259,6 +267,7 @@ private void updateVariablesCache(TerminalNode node, Optional description; + /** + * Тип переменной + */ + String type; + @Override public List getChildren() { return Collections.emptyList(); @@ -183,7 +188,8 @@ public VariableSymbol build() { (short) endCharacter, (short) variableNameLine, (short) variableNameStartCharacter, - (short) variableNameEndCharacter + (short) variableNameEndCharacter, + type ); } else { return new IntBasedVariableSymbol( @@ -200,7 +206,8 @@ public VariableSymbol build() { endCharacter, variableNameLine, variableNameStartCharacter, - variableNameEndCharacter + variableNameEndCharacter, + type ); } } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/IntBasedVariableSymbol.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/IntBasedVariableSymbol.java index 977d18ba6eb..111509b871e 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/IntBasedVariableSymbol.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/IntBasedVariableSymbol.java @@ -73,9 +73,10 @@ public IntBasedVariableSymbol( int endCharacter, int variableNameLine, int variableNameStartCharacter, - int variableNameEndCharacter + int variableNameEndCharacter, + String type ) { - super(name, scope, owner, parent, kind, export, description); + super(name, scope, owner, parent, kind, export, description, type); this.startLine = startLine; this.startCharacter = startCharacter; diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/ShortBasedVariableSymbol.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/ShortBasedVariableSymbol.java index 854661b50b8..81b491f3a1d 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/ShortBasedVariableSymbol.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/ShortBasedVariableSymbol.java @@ -73,9 +73,10 @@ public ShortBasedVariableSymbol( short endCharacter, short variableNameLine, short variableNameStartCharacter, - short variableNameEndCharacter + short variableNameEndCharacter, + String type ) { - super(name, scope, owner, parent, kind, export, description); + super(name, scope, owner, parent, kind, export, description, type); this.startLine = startLine; this.startCharacter = startCharacter; diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/VariableSymbol.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/VariableSymbol.java index 4d5c492459a..2ee888b51f5 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/VariableSymbol.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/VariableSymbol.java @@ -51,6 +51,8 @@ public interface VariableSymbol extends SourceDefinedSymbol, Exportable, Describ */ SourceDefinedSymbol getScope(); + String getType(); + static AbstractVariableSymbol.Builder builder() { return AbstractVariableSymbol.builder(); } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeAfterAsyncCallDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeAfterAsyncCallDiagnostic.java index adb11f9885c..4cef25e0ffb 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeAfterAsyncCallDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeAfterAsyncCallDiagnostic.java @@ -95,7 +95,7 @@ private static boolean checkNextBlocks(BSLParser.StatementContext statement) { final var returnAfterAsync = compoundCtx .map(BSLParser.CompoundStatementContext::returnStatement) .isPresent(); - if (returnAfterAsync){ + if (returnAfterAsync) { return false; } final var breakAfterAsync = compoundCtx diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeOutOfRegionDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeOutOfRegionDiagnostic.java index 6531354ce29..393adb039ac 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeOutOfRegionDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeOutOfRegionDiagnostic.java @@ -72,6 +72,7 @@ public class CodeOutOfRegionDiagnostic extends AbstractVisitorDiagnostic { public ParseTree visitFile(BSLParser.FileContext ctx) { // Для неизвестных модулей не будем требовать нахождения кода в области + // fix me bsl only if (documentContext.getModuleType() == ModuleType.UNKNOWN && !checkUnknownModuleType) { return ctx; } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IdenticalExpressionsDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IdenticalExpressionsDiagnostic.java index 5b81dee5aa8..bfaddc69c2a 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IdenticalExpressionsDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IdenticalExpressionsDiagnostic.java @@ -73,7 +73,7 @@ public class IdenticalExpressionsDiagnostic extends AbstractVisitorDiagnostic { ) private Set popularDivisors = parseCommaSeparatedSet(POPULAR_DIVISORS_DEFAULT_VALUE); private final FormatProvider formatProvider; - + private static Set parseCommaSeparatedSet(String values) { if (values.trim().isEmpty()) { return Collections.emptySet(); diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IncorrectLineBreakDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IncorrectLineBreakDiagnostic.java index 283e1628c7a..4150de910d2 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IncorrectLineBreakDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IncorrectLineBreakDiagnostic.java @@ -104,7 +104,7 @@ protected void check() { findCommentStarts(); findQueryFirstLines(); - if (checkFirstSymbol){ + if (checkFirstSymbol) { checkContent(listOfIncorrectFirstSymbol); } if (checkLastSymbol) { diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IncorrectUseOfStrTemplateDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IncorrectUseOfStrTemplateDiagnostic.java index 1d197d60398..fa6c4a961ed 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IncorrectUseOfStrTemplateDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IncorrectUseOfStrTemplateDiagnostic.java @@ -145,7 +145,7 @@ private static Optional getConstValue(Optional calcStringForMemberContext(memberContext, isFullSearch)); } - private static Optional calcStringForMemberContext(BSLParser.MemberContext memberContext, + private static Optional calcStringForMemberContext(BSLParser.MemberContext memberContext, boolean isFullSearch) { final var constValue = memberContext.constValue(); if (constValue != null) { @@ -161,8 +161,8 @@ private static Optional calcStringForMemberContext( } private static Optional calcAssignedValueForIdentifier( - BSLParser.ComplexIdentifierContext complexIdentifier) { - + BSLParser.ComplexIdentifierContext complexIdentifier) { + final var identifier = complexIdentifier.IDENTIFIER(); if (identifier == null) { return Optional.empty(); @@ -172,9 +172,9 @@ private static Optional calcAssignedValueForIdentif var prevStatement = (BSLParser.StatementContext) Objects.requireNonNull(Trees.getRootParent(complexIdentifier, BSLParser.RULE_statement)); while (true) { - prevStatement = (BSLParser.StatementContext) getPreviousNode(Objects.requireNonNull(prevStatement), + prevStatement = (BSLParser.StatementContext) getPreviousNode(Objects.requireNonNull(prevStatement), BSLParser.RULE_statement); - + if (prevStatement == null) { break; } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UnusedLocalVariableDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UnusedLocalVariableDiagnostic.java index f9308c3caf6..d1a830aaada 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UnusedLocalVariableDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UnusedLocalVariableDiagnostic.java @@ -66,7 +66,10 @@ public void check() { documentContext.getSymbolTree().getVariables().stream() .filter(variable -> CHECKING_VARIABLE_KINDS.contains(variable.getKind())) .filter(variable -> !variable.isExport()) - .filter(variable -> referenceIndex.getReferencesTo(variable).stream().filter(ref -> ref.getOccurrenceType() == OccurrenceType.REFERENCE).findFirst().isEmpty()) - .forEach(variable -> diagnosticStorage.addDiagnostic(variable.getSelectionRange(), info.getMessage(variable.getName()))); + .filter(variable -> referenceIndex.getReferencesTo(variable).stream() + .filter(ref -> ref.getOccurrenceType() == OccurrenceType.REFERENCE).findFirst().isEmpty()) + .forEach(variable -> diagnosticStorage.addDiagnostic( + variable.getSelectionRange(), info.getMessage(variable.getName()) + )); } } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UsingCancelParameterDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UsingCancelParameterDiagnostic.java index 1f3d72eae1d..7dd9c3db25b 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UsingCancelParameterDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UsingCancelParameterDiagnostic.java @@ -69,7 +69,7 @@ public ParseTree visitSub(BSLParser.SubContext ctx) { Trees.findAllRuleNodes(ctx, BSLParser.RULE_assignment).stream() .filter( node -> cancelPattern.matcher(((BSLParser.AssignmentContext) node).lValue() - .getText()) + .getText()) .matches() ) .map(BSLParserRuleContext.class::cast) diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/VariableSymbolMarkupContentBuilder.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/VariableSymbolMarkupContentBuilder.java index 0b442a85e0f..ac220424a1e 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/VariableSymbolMarkupContentBuilder.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/VariableSymbolMarkupContentBuilder.java @@ -69,6 +69,11 @@ public MarkupContent getContent(VariableSymbol symbol) { .map(VariableDescription::getPurposeDescription) .ifPresent(trailingDescription -> addSectionIfNotEmpty(markupBuilder, trailingDescription)); + // todo: Разобраться, почему здесь может быть null. + if (symbol.getType() != null) { + addSectionIfNotEmpty(markupBuilder, symbol.getType()); + } + String content = markupBuilder.toString(); return new MarkupContent(MarkupKind.MARKDOWN, content); diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/ReferencesProvider.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/ReferencesProvider.java index c0b9817079b..396d8404f54 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/ReferencesProvider.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/ReferencesProvider.java @@ -32,7 +32,6 @@ import java.util.Collection; import java.util.List; -import java.util.stream.Collectors; @Component @RequiredArgsConstructor @@ -50,6 +49,6 @@ public List getReferences(DocumentContext documentContext, ReferencePa .map(referenceIndex::getReferencesTo) .flatMap(Collection::stream) .map(Reference::toLocation) - .collect(Collectors.toList()); + .toList(); } } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/references/OscriptReferenceFinder.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/references/OscriptReferenceFinder.java new file mode 100644 index 00000000000..2dc2fd1bb23 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/references/OscriptReferenceFinder.java @@ -0,0 +1,98 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright (c) 2018-2024 + * Alexey Sosnoviy , Nikita Fedkin and contributors + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * BSL Language Server is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * BSL Language Server is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with BSL Language Server. + */ +package com.github._1c_syntax.bsl.languageserver.references; + +import com.github._1c_syntax.bsl.languageserver.context.DocumentState; +import com.github._1c_syntax.bsl.languageserver.context.ServerContext; +import com.github._1c_syntax.bsl.languageserver.context.symbol.SourceDefinedSymbol; +import com.github._1c_syntax.bsl.languageserver.references.model.OccurrenceType; +import com.github._1c_syntax.bsl.languageserver.references.model.Reference; +import com.github._1c_syntax.bsl.languageserver.utils.Ranges; +import com.github._1c_syntax.bsl.languageserver.utils.Trees; +import com.github._1c_syntax.bsl.parser.BSLParser; +import com.github._1c_syntax.bsl.parser.BSLParserRuleContext; +import com.github._1c_syntax.bsl.types.ModuleType; +import lombok.RequiredArgsConstructor; +import org.antlr.v4.runtime.tree.TerminalNode; +import org.eclipse.lsp4j.Position; +import org.springframework.stereotype.Component; + +import java.net.URI; +import java.util.Optional; + +@Component +@RequiredArgsConstructor +public class OscriptReferenceFinder implements ReferenceFinder { + + private final ServerContext serverContext; + + @Override + public Optional findReference(URI uri, Position position) { + + var document = serverContext.getDocument(uri); + if (document == null) { + return Optional.empty(); + } + var documentState = serverContext.getDocumentState(document); + if (documentState == DocumentState.WITHOUT_CONTENT) { + return Optional.empty(); + } + + var maybeTerminalNode = Trees.findTerminalNodeContainsPosition(document.getAst(), position); + + if (maybeTerminalNode.isEmpty()) { + return Optional.empty(); + } + + var terminalNode = maybeTerminalNode.get(); + + var sub = (BSLParser.SubContext) Trees.getAncestorByRuleIndex((BSLParserRuleContext) terminalNode.getParent().getRuleContext(), BSLParser.RULE_sub); + var symbolTree = document.getSymbolTree(); + var from = Optional.ofNullable(sub) + .flatMap(symbolTree::getMethodSymbol) + .map(SourceDefinedSymbol.class::cast) + .orElse(symbolTree.getModule()); + + return serverContext.getDocuments().values().stream() + .filter(documentContext -> documentContext.getTypeName().equals(terminalNode.getText())) + .filter(documentContext -> filterByType(terminalNode, documentContext.getModuleType())) + .map(documentContext -> new Reference( + // todo: было бы здорово сохранить эту информацию в ReferenceIndex вместо поиска напрямую. + from, + documentContext.getSymbolTree().getModule(), + documentContext.getUri(), + Ranges.create(terminalNode), + OccurrenceType.DEFINITION) + ).findAny(); + + } + + private boolean filterByType(TerminalNode node, ModuleType moduleType) { + if ((node.getParent() instanceof BSLParser.TypeNameContext) + && moduleType == ModuleType.OScriptClass) { + return true; + } else { + return (node.getParent() instanceof BSLParser.ComplexIdentifierContext) + && moduleType == ModuleType.OScriptModule; + } + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/references/ReferenceIndex.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/references/ReferenceIndex.java index 0b478d6daea..e6fc37ebb16 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/references/ReferenceIndex.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/references/ReferenceIndex.java @@ -70,7 +70,7 @@ public List getReferencesTo(SourceDefinedSymbol symbol) { var mdoRef = MdoRefBuilder.getMdoRef(symbol.getOwner()); var moduleType = symbol.getOwner().getModuleType(); var symbolName = symbol.getName().toLowerCase(Locale.ENGLISH); - String scopeName = ""; + var scopeName = ""; if (symbol.getSymbolKind() == SymbolKind.Variable) { scopeName = symbol.getRootParent(SymbolKind.Method) @@ -164,13 +164,14 @@ public void clearReferences(URI uri) { * Добавить вызов метода в индекс. * * @param uri URI документа, откуда произошел вызов. - * @param mdoRef Ссылка на объект-метаданных, к которому происходит обращение (например, CommonModule.ОбщийМодуль1). + * @param mdoRef Ссылка на объект-метаданных, к которому происходит обращение + * (например, CommonModule.ОбщийМодуль1). * @param moduleType Тип модуля, к которому происходит обращение (например, {@link ModuleType#CommonModule}). * @param symbolName Имя символа, к которому происходит обращение. * @param range Диапазон, в котором происходит обращение к символу. */ public void addMethodCall(URI uri, String mdoRef, ModuleType moduleType, String symbolName, Range range) { - String symbolNameCanonical = stringInterner.intern(symbolName.toLowerCase(Locale.ENGLISH)); + var symbolNameCanonical = stringInterner.intern(symbolName.toLowerCase(Locale.ENGLISH)); var symbol = Symbol.builder() .mdoRef(mdoRef) @@ -196,12 +197,13 @@ public void addMethodCall(URI uri, String mdoRef, ModuleType moduleType, String * Добавить обращение к переменной в индекс. * * @param uri URI документа, откуда произошел вызов. - * @param mdoRef Ссылка на объект-метаданных, к которому происходит обращение (например, CommonModule.ОбщийМодуль1). + * @param mdoRef Ссылка на объект-метаданных, к которому происходит обращение + * (например, CommonModule.ОбщийМодуль1). * @param moduleType Тип модуля, к которому происходит обращение (например, {@link ModuleType#CommonModule}). * @param methodName Имя метода, к которому относиться перменная. Пустой если переменная относиться к модулю. * @param variableName Имя переменной, к которой происходит обращение. * @param range Диапазон, в котором происходит обращение к символу. - * @param definition Признак обновления значения переменной. + * @param definition Признак обновления значения переменной. */ public void addVariableUsage(URI uri, String mdoRef, @@ -210,8 +212,8 @@ public void addVariableUsage(URI uri, String variableName, Range range, boolean definition) { - String methodNameCanonical = stringInterner.intern(methodName.toLowerCase(Locale.ENGLISH)); - String variableNameCanonical = stringInterner.intern(variableName.toLowerCase(Locale.ENGLISH)); + var methodNameCanonical = stringInterner.intern(methodName.toLowerCase(Locale.ENGLISH)); + var variableNameCanonical = stringInterner.intern(variableName.toLowerCase(Locale.ENGLISH)); var symbol = Symbol.builder() .mdoRef(mdoRef) @@ -252,15 +254,15 @@ private Optional buildReference( private Optional getSourceDefinedSymbol(Symbol symbolEntity) { String mdoRef = symbolEntity.getMdoRef(); - ModuleType moduleType = symbolEntity.getModuleType(); + var moduleType = symbolEntity.getModuleType(); String symbolName = symbolEntity.getSymbolName(); if (symbolEntity.getSymbolKind() == SymbolKind.Variable) { return serverContext.getDocument(mdoRef, moduleType) .map(DocumentContext::getSymbolTree) .flatMap(symbolTree -> symbolTree.getMethodSymbol(symbolEntity.getScopeName()) - .flatMap(method -> symbolTree.getVariableSymbol(symbolName, method)) - .or(() -> symbolTree.getVariableSymbol(symbolName, symbolTree.getModule()))); + .flatMap(method -> symbolTree.getVariableSymbol(symbolName, method)) + .or(() -> symbolTree.getVariableSymbol(symbolName, symbolTree.getModule()))); } return serverContext.getDocument(mdoRef, moduleType) diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/references/model/Location.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/references/model/Location.java index e18daea9bc4..cc41a63a191 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/references/model/Location.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/references/model/Location.java @@ -72,7 +72,7 @@ public Location(URI uri, Range range) { endCharacter = end.getCharacter(); } - + public Range getRange() { return Ranges.create(startLine, startCharacter, endLine, endCharacter); } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Modules.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Modules.java index 2c09c0aeafe..5234a732ddd 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Modules.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Modules.java @@ -36,7 +36,7 @@ public class Modules { public static boolean isThisObject(BSLParser.ComplexIdentifierContext complexIdentifier) { final var identifier = complexIdentifier.IDENTIFIER(); - if (identifier == null){ + if (identifier == null) { return false; } return THIS_OBJECT_PATTERN.matcher(identifier.getText()).matches(); diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Ranges.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Ranges.java index 95f30eda4db..d0aa578d8bd 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Ranges.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Ranges.java @@ -155,11 +155,11 @@ public boolean containsPosition(Range range, Position position) { * @return 0 - равно, 1 - больше, -1 - меньше */ public int compare(Range o1, Range o2) { - if (o1.equals(o2)){ + if (o1.equals(o2)) { return 0; } final var startCompare = compare(o1.getStart(), o2.getStart()); - if (startCompare != 0){ + if (startCompare != 0) { return startCompare; } return compare(o1.getEnd(), o2.getEnd()); @@ -173,7 +173,7 @@ public int compare(Range o1, Range o2) { * @return 0 - равно, 1 - больше, -1 - меньше */ public int compare(Position pos1, Position pos2) { - if (pos1.equals(pos2)){ + if (pos1.equals(pos2)) { return 0; } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/BslExpression.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/BslExpression.java index 76bc9dc1da0..0294ed42bf6 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/BslExpression.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/BslExpression.java @@ -38,11 +38,12 @@ public abstract class BslExpression { /** * Синтаксический-помощник для более удобных downcast-ов + * * @param тип, к которому надо привести данный узел * @return значение заданного типа */ @SuppressWarnings("unchecked") public T cast() { - return (T)this; + return (T) this; } } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ConstructorCallNode.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ConstructorCallNode.java index 8c86c700cab..b7487ce7f21 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ConstructorCallNode.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ConstructorCallNode.java @@ -45,6 +45,7 @@ public boolean isStaticallyTyped() { /** * Конструирование статического вызова конструктора + * * @param typeName терминальный символ имени типа * @return ветка конструктора */ @@ -54,6 +55,7 @@ public static ConstructorCallNode createStatic(TerminalSymbolNode typeName) { /** * Конструирование вызова конструктора в функциональном стиле + * * @param typeNameExpression подвыражение с именем типа * @return ветка конструктора */ diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionParseTreeRewriter.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionParseTreeRewriter.java index c580191eb8d..db6f677cbba 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionParseTreeRewriter.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionParseTreeRewriter.java @@ -29,7 +29,7 @@ */ public final class ExpressionParseTreeRewriter { - private ExpressionParseTreeRewriter(){ + private ExpressionParseTreeRewriter() { } /** diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/TernaryOperatorNode.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/TernaryOperatorNode.java index ef87a7c77be..de46c422ee9 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/TernaryOperatorNode.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/TernaryOperatorNode.java @@ -37,7 +37,7 @@ public class TernaryOperatorNode extends BslExpression { BslExpression truePart; BslExpression falsePart; - protected TernaryOperatorNode(BslExpression condition, BslExpression truePart, BslExpression falsePart) { + private TernaryOperatorNode(BslExpression condition, BslExpression truePart, BslExpression falsePart) { super(ExpressionNodeType.TERNARY_OP); this.condition = condition; this.truePart = truePart; diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/UnaryOperationNode.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/UnaryOperationNode.java index 940390ee30e..bc159387776 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/UnaryOperationNode.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/UnaryOperationNode.java @@ -40,9 +40,11 @@ private UnaryOperationNode(BslOperator operator, BslExpression operand, ParseTre this.operand = operand; } - /** Конструирует унарную операцию - * @param operator оператор - * @param expression аргумент операции + /** + * Конструирует унарную операцию + * + * @param operator оператор + * @param expression аргумент операции * @param operationContext строковое представление оператора, * как он указан в коде с учетом регистра и языка. * Используется в диагностических сообщениях. diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContextTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContextTest.java index 10cea84790d..6e9827fdd71 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContextTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContextTest.java @@ -239,4 +239,17 @@ void testEOF() { assertThat(lastToken.getType()).isEqualTo(Lexer.EOF); assertThat(lastToken.getChannel()).isEqualTo(Lexer.HIDDEN); } + + @Test + void testOSTypes(){ + + // given + var documentContext = getDocumentContext("./src/test/resources/metadata/oscript/Классы/ТестовыйКласс.os"); + // when + var typeName = documentContext.getTypeName(); + // then + assertThat(typeName).isEqualTo("ТестовыйКласс"); + + } + } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/computer/VariableSymbolTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/computer/VariableSymbolTest.java index 152daa91ce3..50c39584793 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/computer/VariableSymbolTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/computer/VariableSymbolTest.java @@ -144,4 +144,13 @@ void testVariableKind() { } + @Test + void testVariableNewOS() { + + documentContext = TestUtils.getDocumentContextFromFile("./src/test/resources/context/symbol/variableSymbolTest.os"); + variableSymbols = documentContext.getSymbolTree().getVariables(); + + assertThat(variableSymbols.get(0).getType()).isEqualTo("МойКласс"); + } + } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/ForbiddenMetadataNameDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/ForbiddenMetadataNameDiagnosticTest.java index 1d21cb0ab0a..241e8d25389 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/ForbiddenMetadataNameDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/ForbiddenMetadataNameDiagnosticTest.java @@ -161,4 +161,4 @@ void testAllMDO() { .anyMatch(diagnostic -> diagnostic.getMessage().contains("для `РегистрСведений.РегистрСведений")) ; } -} +} \ No newline at end of file diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/hover/VariableSymbolMarkupContentBuilderTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/hover/VariableSymbolMarkupContentBuilderTest.java index b8ade4cb595..72bbb6715ac 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/hover/VariableSymbolMarkupContentBuilderTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/hover/VariableSymbolMarkupContentBuilderTest.java @@ -146,6 +146,25 @@ void testMethodVarContentFromDirectFile_2_comments_strings() { """); } + @Test + void testMethodVarContentFromDirectFile_type_from_new() { + // given + var documentContext = TestUtils.getDocumentContextFromFile(PATH_TO_FILE); + final var symbolTree = documentContext.getSymbolTree(); + var methodSymbol = symbolTree.getMethodSymbol("ИмяФункции").orElseThrow(); + var varSymbol = symbolTree.getVariableSymbol("НовыйКласс", methodSymbol).orElseThrow(); + + // when + var content = markupContentBuilder.getContent(varSymbol).getValue(); + + assertThat(content).isNotEmpty(); + + var blocks = Arrays.asList(content.split("---\n?")); + + assertThat(blocks).hasSize(3); + assertThat(blocks.get(2)).isEqualTo("ИмяКласса\n\n"); + } + @Test void testMethodVarContentFromDirectFile_3_comments_strings() { // given diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/ReferencesProviderTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/ReferencesProviderTest.java index 68b92f76b85..ba22a663157 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/ReferencesProviderTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/ReferencesProviderTest.java @@ -22,14 +22,14 @@ package com.github._1c_syntax.bsl.languageserver.providers; import com.github._1c_syntax.bsl.languageserver.context.ServerContext; -import com.github._1c_syntax.bsl.languageserver.util.CleanupContextBeforeClassAndAfterClass; +import com.github._1c_syntax.bsl.languageserver.util.CleanupContextBeforeClassAndAfterEachTestMethod; import com.github._1c_syntax.bsl.languageserver.util.TestUtils; import com.github._1c_syntax.bsl.languageserver.utils.Ranges; import com.github._1c_syntax.bsl.types.ModuleType; -import jakarta.annotation.PostConstruct; import org.eclipse.lsp4j.Location; import org.eclipse.lsp4j.Position; import org.eclipse.lsp4j.ReferenceParams; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -40,7 +40,7 @@ import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest -@CleanupContextBeforeClassAndAfterClass +@CleanupContextBeforeClassAndAfterEachTestMethod class ReferencesProviderTest { @Autowired @@ -51,7 +51,7 @@ class ReferencesProviderTest { private static final String PATH_TO_FILE = "./src/test/resources/providers/references.bsl"; - @PostConstruct + @BeforeEach void prepareServerContext() { serverContext.setConfigurationRoot(Paths.get(PATH_TO_METADATA)); serverContext.populateContext(); diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/references/OscriptReferenceFinderTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/references/OscriptReferenceFinderTest.java new file mode 100644 index 00000000000..a7d8c029d20 --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/references/OscriptReferenceFinderTest.java @@ -0,0 +1,75 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright (c) 2018-2024 + * Alexey Sosnoviy , Nikita Fedkin and contributors + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * BSL Language Server is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * BSL Language Server is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with BSL Language Server. + */ +package com.github._1c_syntax.bsl.languageserver.references; + +import com.github._1c_syntax.bsl.languageserver.context.ServerContext; +import com.github._1c_syntax.bsl.languageserver.util.TestUtils; +import com.github._1c_syntax.utils.Absolute; +import org.eclipse.lsp4j.Position; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +class OscriptReferenceFinderTest { + + @Autowired + private OscriptReferenceFinder referenceFinder; + + @Autowired + private ServerContext serverContext; + + @Test + void testFindReferenceToClass() { + // given + serverContext.setConfigurationRoot(Absolute.path("src/test/resources/metadata/oscript")); + serverContext.populateContext(); + var mainOsContext = TestUtils.getDocumentContextFromFile("./src/test/resources/metadata/oscript/main.os"); + + // when + var optionalReference = referenceFinder.findReference(mainOsContext.getUri(), new Position(1, 25)); + + // then + assertThat(optionalReference).isPresent(); + } + + @Test + void testFindReferenceToModule() { + // given + serverContext.setConfigurationRoot(Absolute.path("src/test/resources/metadata/oscript")); + serverContext.populateContext(); + var mainOsContext = TestUtils.getDocumentContextFromFile("./src/test/resources/metadata/oscript/main.os"); + + // when + var optionalReference = referenceFinder.findReference(mainOsContext.getUri(), new Position(3, 17)); + // then + assertThat(optionalReference).isPresent(); + + // when + var variable = referenceFinder.findReference(mainOsContext.getUri(), new Position(3, 53)); + // then + assertThat(variable).isEmpty(); + } + +} diff --git a/src/test/resources/context/symbol/variableSymbolTest.os b/src/test/resources/context/symbol/variableSymbolTest.os new file mode 100644 index 00000000000..bd5d74624d6 --- /dev/null +++ b/src/test/resources/context/symbol/variableSymbolTest.os @@ -0,0 +1,3 @@ +Процедура В() + А = Новый МойКласс(); +КонецПроцедуры \ No newline at end of file diff --git a/src/test/resources/hover/variableSymbolMarkupContentBuilder.bsl b/src/test/resources/hover/variableSymbolMarkupContentBuilder.bsl index 0d695bccd08..bf0dc3065de 100644 --- a/src/test/resources/hover/variableSymbolMarkupContentBuilder.bsl +++ b/src/test/resources/hover/variableSymbolMarkupContentBuilder.bsl @@ -32,6 +32,7 @@ // Перем Имя_ОписаниеСверхуТриСтрокиПоследняяПустая_Функция; + НовыйКласс = Новый ИмяКласса(); КонецФункции ИмяФункции(); diff --git a/src/test/resources/metadata/oscript/main.os b/src/test/resources/metadata/oscript/main.os new file mode 100644 index 00000000000..8735f266dc2 --- /dev/null +++ b/src/test/resources/metadata/oscript/main.os @@ -0,0 +1,4 @@ + +ТестовыйКласс = Новый ТестовыйКласс; + +Другая = ТестовыйМодуль.ЭкспортныйМетод() + ТестовыйКласс; diff --git "a/src/test/resources/metadata/oscript/\320\232\320\273\320\260\321\201\321\201\321\213/\320\242\320\265\321\201\321\202\320\276\320\262\321\213\320\271\320\232\320\273\320\260\321\201\321\201.os" "b/src/test/resources/metadata/oscript/\320\232\320\273\320\260\321\201\321\201\321\213/\320\242\320\265\321\201\321\202\320\276\320\262\321\213\320\271\320\232\320\273\320\260\321\201\321\201.os" new file mode 100644 index 00000000000..36484ceffea --- /dev/null +++ "b/src/test/resources/metadata/oscript/\320\232\320\273\320\260\321\201\321\201\321\213/\320\242\320\265\321\201\321\202\320\276\320\262\321\213\320\271\320\232\320\273\320\260\321\201\321\201.os" @@ -0,0 +1,10 @@ + +Процедура ПростоПроцедура() + + +КонецПроцедуры + +Процедура ПриСозданииОбъекта() + + +КонецПроцедуры \ No newline at end of file diff --git "a/src/test/resources/metadata/oscript/\320\234\320\276\320\264\321\203\320\273\320\270/\320\242\320\265\321\201\321\202\320\276\320\262\321\213\320\271\320\234\320\276\320\264\321\203\320\273\321\214.os" "b/src/test/resources/metadata/oscript/\320\234\320\276\320\264\321\203\320\273\320\270/\320\242\320\265\321\201\321\202\320\276\320\262\321\213\320\271\320\234\320\276\320\264\321\203\320\273\321\214.os" new file mode 100644 index 00000000000..879b632d202 --- /dev/null +++ "b/src/test/resources/metadata/oscript/\320\234\320\276\320\264\321\203\320\273\320\270/\320\242\320\265\321\201\321\202\320\276\320\262\321\213\320\271\320\234\320\276\320\264\321\203\320\273\321\214.os" @@ -0,0 +1,8 @@ + +Процедура ПростоМетод() + +КонецПроцедуры + +Процедура ЭкспортныйМетод() Экспорт + ПростоМетод(); +КонецПроцедуры