diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/PrivilegedModuleMethodCallDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/PrivilegedModuleMethodCallDiagnostic.java index bbc18df210e..b2bab8ad94a 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/PrivilegedModuleMethodCallDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/PrivilegedModuleMethodCallDiagnostic.java @@ -23,6 +23,7 @@ import com.github._1c_syntax.bsl.languageserver.context.symbol.ModuleSymbol; import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticMetadata; +import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticParameter; import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticScope; import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticSeverity; import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticTag; @@ -49,18 +50,18 @@ ) @RequiredArgsConstructor public class PrivilegedModuleMethodCallDiagnostic extends AbstractDiagnostic { + + private static final boolean VALIDATE_NESTED_CALLS = true; + + @DiagnosticParameter( + type = Boolean.class, + defaultValue = "" + VALIDATE_NESTED_CALLS + ) + private boolean validateNestedCalls = VALIDATE_NESTED_CALLS; + private final ReferenceIndex referenceIndex; private List privilegedModuleSymbols = new ArrayList<>(); - private static boolean isReferenceToModules(Reference reference, List privilegedModuleSymbols) { - return reference.getSourceDefinedSymbol() - .flatMap(sourceDefinedSymbol -> sourceDefinedSymbol.getRootParent(SymbolKind.Module)) - .filter(ModuleSymbol.class::isInstance) - .map(ModuleSymbol.class::cast) - .filter(privilegedModuleSymbols::contains) - .isPresent(); - } - @Override protected void check() { if (privilegedModuleSymbols.isEmpty()){ @@ -71,7 +72,7 @@ protected void check() { } referenceIndex.getReferencesFrom(documentContext.getUri(), SymbolKind.Method).stream() - .filter(reference -> isReferenceToModules(reference, privilegedModuleSymbols)) + .filter(this::isReferenceToModules) .forEach(this::fireIssue); } @@ -89,6 +90,18 @@ private Optional getPrivilegedModuleSymbol(MDCommonModule mdCommon .map(documentContext1 -> documentContext1.getSymbolTree().getModule()); } + private boolean isReferenceToModules(Reference reference) { + if (!validateNestedCalls && reference.getUri().equals(documentContext.getUri())){ + return false; + } + return reference.getSourceDefinedSymbol() + .flatMap(sourceDefinedSymbol -> sourceDefinedSymbol.getRootParent(SymbolKind.Module)) + .filter(ModuleSymbol.class::isInstance) + .map(ModuleSymbol.class::cast) + .filter(privilegedModuleSymbols::contains) + .isPresent(); + } + private void fireIssue(Reference reference) { diagnosticStorage.addDiagnostic(reference.getSelectionRange(), info.getMessage(reference.getSymbol().getName())); diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/configuration/parameters-schema.json b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/configuration/parameters-schema.json index cb8891995eb..08feceabd85 100644 --- a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/configuration/parameters-schema.json +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/configuration/parameters-schema.json @@ -1478,6 +1478,14 @@ "object" ], "title": "Accessing privileged module methods", + "properties": { + "validateNestedCalls": { + "description": "Validate nested method calls from privileged modules", + "default": true, + "type": "boolean", + "title": "Validate nested method calls from privileged modules" + } + }, "$id": "#/definitions/PrivilegedModuleMethodCall" }, "ProcedureReturnsValue": { diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/PrivilegedModuleMethodCallDiagnostic_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/PrivilegedModuleMethodCallDiagnostic_en.properties index 60269b66c95..eb7fdf7c62c 100644 --- a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/PrivilegedModuleMethodCallDiagnostic_en.properties +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/PrivilegedModuleMethodCallDiagnostic_en.properties @@ -1,2 +1,3 @@ diagnosticMessage=Check the %s method access of the privileged module -diagnosticName=Accessing privileged module methods \ No newline at end of file +diagnosticName=Accessing privileged module methods +validateNestedCalls=Validate nested method calls from privileged modules diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/PrivilegedModuleMethodCallDiagnostic_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/PrivilegedModuleMethodCallDiagnostic_ru.properties index 92318fdcdf9..e350b71eecf 100644 --- a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/PrivilegedModuleMethodCallDiagnostic_ru.properties +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/PrivilegedModuleMethodCallDiagnostic_ru.properties @@ -1,2 +1,3 @@ diagnosticMessage=Проверьте обращение к методу %s привилегированного модуля diagnosticName=Обращение к методам привилегированных модулей +validateNestedCalls=Проверять вложенные вызовы методов из привилегированных модулей diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/PrivilegedModuleMethodCallDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/PrivilegedModuleMethodCallDiagnosticTest.java index d639627a96a..e1323becebb 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/PrivilegedModuleMethodCallDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/PrivilegedModuleMethodCallDiagnosticTest.java @@ -24,22 +24,34 @@ import org.eclipse.lsp4j.Diagnostic; import org.junit.jupiter.api.Test; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.List; +import java.util.Map; import static com.github._1c_syntax.bsl.languageserver.util.Assertions.assertThat; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; class PrivilegedModuleMethodCallDiagnosticTest extends AbstractDiagnosticTest { private static final String PATH_TO_METADATA = "src/test/resources/metadata/privilegedModules"; + private static final String PATH_TO_MODULE_FILE = PATH_TO_METADATA + "/CommonModules/ПривилегированныйМодуль1/Ext/Module.bsl"; PrivilegedModuleMethodCallDiagnosticTest() { super(PrivilegedModuleMethodCallDiagnostic.class); } + @Test + void testWithoutMetadata() { + var diagnostics = getDiagnostics(); + assertThat(diagnostics).isEmpty(); + } + @Test void test() { initServerContext(PATH_TO_METADATA); - List diagnostics = getDiagnostics(); + var diagnostics = getDiagnostics(); assertThat(diagnostics).hasSize(2); assertThat(diagnostics, true) @@ -48,9 +60,32 @@ void test() { } @Test - void testWithoutMetadata() { + void getNestedCalls() { + var diagnostics = getDiagnosticsAsCommonModule(); + assertThat(diagnostics).hasSize(2); + assertThat(diagnostics, true) + .hasMessageOnRange("Проверьте обращение к методу ПубличнаяФункция привилегированного модуля", 15, 15, 31) + .hasMessageOnRange("Проверьте обращение к методу ПубличнаяПроцедура привилегированного модуля", 19, 4, 22); + } - List diagnostics = getDiagnostics(); + @Test + void testParameterValidateNestedCalls() { + Map configuration = diagnosticInstance.getInfo().getDefaultConfiguration(); + configuration.put("validateNestedCalls", false); + diagnosticInstance.configure(configuration); + + var diagnostics = getDiagnosticsAsCommonModule(); assertThat(diagnostics).isEmpty(); } + + private List getDiagnosticsAsCommonModule() { + Path moduleFile = Paths.get(PATH_TO_MODULE_FILE).toAbsolutePath(); + + initServerContext(PATH_TO_METADATA); + + var documentContext = spy(getDocumentContext(diagnosticInstance.getClass().getSimpleName())); + when(documentContext.getUri()).thenReturn(moduleFile.toUri()); + + return getDiagnostics(documentContext); + } } diff --git "a/src/test/resources/metadata/privilegedModules/CommonModules/\320\237\321\200\320\270\320\262\320\270\320\273\320\265\320\263\320\270\321\200\320\276\320\262\320\260\320\275\320\275\321\213\320\271\320\234\320\276\320\264\321\203\320\273\321\2141/Ext/Module.bsl" "b/src/test/resources/metadata/privilegedModules/CommonModules/\320\237\321\200\320\270\320\262\320\270\320\273\320\265\320\263\320\270\321\200\320\276\320\262\320\260\320\275\320\275\321\213\320\271\320\234\320\276\320\264\321\203\320\273\321\2141/Ext/Module.bsl" index 626fd1e6394..f7d88c16cfd 100644 --- "a/src/test/resources/metadata/privilegedModules/CommonModules/\320\237\321\200\320\270\320\262\320\270\320\273\320\265\320\263\320\270\321\200\320\276\320\262\320\260\320\275\320\275\321\213\320\271\320\234\320\276\320\264\321\203\320\273\321\2141/Ext/Module.bsl" +++ "b/src/test/resources/metadata/privilegedModules/CommonModules/\320\237\321\200\320\270\320\262\320\270\320\273\320\265\320\263\320\270\321\200\320\276\320\262\320\260\320\275\320\275\321\213\320\271\320\234\320\276\320\264\321\203\320\273\321\2141/Ext/Module.bsl" @@ -13,11 +13,11 @@ #Область СлужебныеПроцедурыИФункции Функция ПриватнаяФункция() - + Значение = ПубличнаяФункция(); КонецФункции Процедура ПриватнаяПроцедура() - + ПубличнаяПроцедура(); КонецПроцедуры #КонецОбласти