Skip to content

Commit ef8438b

Browse files
authored
Merge pull request #3187 from AlexPCRus/alexpc-patch-2
Новая диагностика "Зарезервированные имена параметров"
2 parents 5f877fb + 245220a commit ef8438b

File tree

9 files changed

+238
-0
lines changed

9 files changed

+238
-0
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Зарезервированные имена параметра (ReservedParameterNames)
2+
3+
<!-- Блоки выше заполняются автоматически, не трогать -->
4+
## Описание диагностики
5+
Если имя параметра совпадает с именем системного перечисления, то невозможно будет обратиться к значениям этого системного перечисления, потому что параметр его скроет.
6+
Синтаксическая проверка кода модуля не выявит такую ошибку. Чтобы предотвратить эту ситуацию имя параметра не должно совпадать с именами системных перечислений.
7+
Список зарезервированных слов задается регулярным выражением.
8+
Поиск производится без учета регистра символов.
9+
10+
**Примеры настройки:**
11+
12+
"ВидГруппыФормы|ВидПоляФормы"
13+
14+
## Источники
15+
<!-- Необходимо указывать ссылки на все источники, из которых почерпнута информация для создания диагностики -->
16+
17+
* Источник: [Стандарт: Параметры процедур и функций](https://its.1c.ru/db/v8std/content/640/hdoc)
18+
* Источник: [Стандарт: Правила образования имен переменных](https://its.1c.ru/db/v8std#content:454:hdoc)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Reserved parameter names (ReservedParameterNames)
2+
3+
<!-- Блоки выше заполняются автоматически, не трогать -->
4+
## Description
5+
6+
7+
If a parameter name matches one of a system enumeration's name, then all values of that enumeration will not be available in the local context.
8+
Module code's syntax checking will not detect an error. To prevent this situation, a parameter name should not match all names of system enumerations.
9+
10+
Parameter names should not contain reserved words such as system enumerations.
11+
The list of reserved words is set by a regular expression.
12+
The search is case-insensitive.
13+
14+
**For example:**
15+
16+
"FormGroupType|FormFieldType"
17+
18+
## Sources
19+
<!-- Необходимо указывать ссылки на все источники, из которых почерпнута информация для создания диагностики -->
20+
21+
* Source: [Standard: Procedure and Function Parameters (RU)](https://its.1c.ru/db/v8std/content/640/hdoc)
22+
* Source: [Standard: Rules for generating variable names (RU)](https://its.1c.ru/db/v8std#content:454:hdoc)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* This file is a part of BSL Language Server.
3+
*
4+
* Copyright (c) 2018-2024
5+
* Alexey Sosnoviy <labotamy@gmail.com>, Nikita Fedkin <nixel2007@gmail.com> and contributors
6+
*
7+
* SPDX-License-Identifier: LGPL-3.0-or-later
8+
*
9+
* BSL Language Server is free software; you can redistribute it and/or
10+
* modify it under the terms of the GNU Lesser General Public
11+
* License as published by the Free Software Foundation; either
12+
* version 3.0 of the License, or (at your option) any later version.
13+
*
14+
* BSL Language Server is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17+
* Lesser General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Lesser General Public
20+
* License along with BSL Language Server.
21+
*/
22+
package com.github._1c_syntax.bsl.languageserver.diagnostics;
23+
24+
import com.github._1c_syntax.bsl.languageserver.context.symbol.MethodSymbol;
25+
import com.github._1c_syntax.bsl.languageserver.context.symbol.ParameterDefinition;
26+
import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticMetadata;
27+
import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticParameter;
28+
import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticSeverity;
29+
import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticTag;
30+
import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticType;
31+
32+
import com.github._1c_syntax.utils.CaseInsensitivePattern;
33+
34+
import java.util.List;
35+
import java.util.Map;
36+
import java.util.regex.Pattern;
37+
38+
@DiagnosticMetadata(
39+
type = DiagnosticType.CODE_SMELL,
40+
severity = DiagnosticSeverity.MAJOR,
41+
minutesToFix = 5,
42+
tags = {
43+
DiagnosticTag.STANDARD,
44+
DiagnosticTag.BADPRACTICE
45+
}
46+
)
47+
public class ReservedParameterNamesDiagnostic extends AbstractSymbolTreeDiagnostic {
48+
49+
private static final String RESERVED_WORDS_DEFAULT = "";
50+
51+
@DiagnosticParameter(type = String.class)
52+
private Pattern reservedWords = CaseInsensitivePattern.compile(RESERVED_WORDS_DEFAULT);
53+
54+
@Override
55+
public void configure(Map<String, Object> configuration) {
56+
57+
var incomingMask = (String) configuration.getOrDefault("reservedWords", RESERVED_WORDS_DEFAULT);
58+
59+
this.reservedWords = CaseInsensitivePattern.compile("^" + incomingMask.trim() + "$");
60+
}
61+
62+
@Override
63+
protected void check() {
64+
65+
if (reservedWords.pattern().isBlank()) {
66+
return;
67+
}
68+
super.check();
69+
}
70+
71+
@Override
72+
public void visitMethod(MethodSymbol methodSymbol) {
73+
74+
List<ParameterDefinition> parameters = methodSymbol.getParameters();
75+
checkParameterName(parameters);
76+
}
77+
78+
private void checkParameterName(List<ParameterDefinition> parameters) {
79+
80+
parameters.forEach((ParameterDefinition parameter) -> {
81+
82+
var matcher = reservedWords.matcher(parameter.getName());
83+
if (matcher.find()) {
84+
diagnosticStorage.addDiagnostic(parameter.getRange(), info.getMessage(parameter.getName()));
85+
}
86+
});
87+
}
88+
89+
}

src/main/resources/com/github/_1c_syntax/bsl/languageserver/configuration/parameters-schema.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,6 +1670,24 @@
16701670
"title": "Overuse \"Reference\" in a query",
16711671
"$id": "#/definitions/RefOveruse"
16721672
},
1673+
"ReservedParameterNames": {
1674+
"description": "Reserved parameter names",
1675+
"default": false,
1676+
"type": [
1677+
"boolean",
1678+
"object"
1679+
],
1680+
"title": "Reserved parameter names",
1681+
"properties": {
1682+
"reservedWords": {
1683+
"description": "Regular expression for reserved parameter names.",
1684+
"default": "",
1685+
"type": "string",
1686+
"title": "Regular expression for reserved parameter names."
1687+
}
1688+
},
1689+
"$id": "#/definitions/ReservedParameterNames"
1690+
},
16731691
"RewriteMethodParameter": {
16741692
"description": "Rewrite method parameter",
16751693
"default": true,

src/main/resources/com/github/_1c_syntax/bsl/languageserver/configuration/schema.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,9 @@
386386
"RefOveruse": {
387387
"$ref": "parameters-schema.json#/definitions/RefOveruse"
388388
},
389+
"ReservedParameterNames": {
390+
"$ref": "parameters-schema.json#/definitions/ReservedParameterNames"
391+
},
389392
"RewriteMethodParameter": {
390393
"$ref": "parameters-schema.json#/definitions/RewriteMethodParameter"
391394
},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
diagnosticMessage=Rename parameter "%s" that matches one of reserved words.
2+
diagnosticName=Reserved parameter names
3+
reservedWords=Regular expression for reserved parameter names.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
diagnosticMessage=Переименуйте параметр "%s" так, чтобы он не совпадал с зарезервированным словом.
2+
diagnosticName=Зарезервированные имена параметров
3+
reservedWords=Регулярное выражение для зарезервированных имен параметров.
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* This file is a part of BSL Language Server.
3+
*
4+
* Copyright (c) 2018-2024
5+
* Alexey Sosnoviy <labotamy@gmail.com>, Nikita Fedkin <nixel2007@gmail.com> and contributors
6+
*
7+
* SPDX-License-Identifier: LGPL-3.0-or-later
8+
*
9+
* BSL Language Server is free software; you can redistribute it and/or
10+
* modify it under the terms of the GNU Lesser General Public
11+
* License as published by the Free Software Foundation; either
12+
* version 3.0 of the License, or (at your option) any later version.
13+
*
14+
* BSL Language Server is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17+
* Lesser General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Lesser General Public
20+
* License along with BSL Language Server.
21+
*/
22+
package com.github._1c_syntax.bsl.languageserver.diagnostics;
23+
24+
import org.eclipse.lsp4j.Diagnostic;
25+
import org.junit.jupiter.api.Test;
26+
27+
import java.util.List;
28+
import java.util.Map;
29+
30+
import org.junit.jupiter.params.ParameterizedTest;
31+
import org.junit.jupiter.params.provider.ValueSource;
32+
33+
import static com.github._1c_syntax.bsl.languageserver.util.Assertions.assertThat;
34+
35+
class ReservedParameterNamesDiagnosticTest extends AbstractDiagnosticTest<ReservedParameterNamesDiagnostic> {
36+
ReservedParameterNamesDiagnosticTest() {
37+
super(ReservedParameterNamesDiagnostic.class);
38+
}
39+
40+
@Test
41+
void testEmpty() {
42+
List<Diagnostic> diagnostics = getDiagnostics();
43+
assertThat(diagnostics).isEmpty();
44+
}
45+
46+
@Test
47+
void testPositive() {
48+
49+
Map<String, Object> configuration = diagnosticInstance.info.getDefaultConfiguration();
50+
configuration.put("reservedWords", "ВидГруппыФормы");
51+
diagnosticInstance.configure(configuration);
52+
53+
List<Diagnostic> diagnostics = getDiagnostics();
54+
55+
assertThat(diagnostics).hasSize(1);
56+
assertThat(diagnostics, true)
57+
.hasMessageOnRange("Переименуйте параметр \"ВидГруппыФормы\" чтобы он не совпадал с зарезервированным словом.",
58+
2, 16, 30);
59+
60+
}
61+
62+
@ParameterizedTest
63+
@ValueSource(strings = {" ", "ВидГруппы", "ВидГруппыФормыРасширенный"})
64+
void testNegative(String testWord) {
65+
66+
Map<String, Object> configuration = diagnosticInstance.info.getDefaultConfiguration();
67+
configuration.put("reservedWords", testWord);
68+
diagnosticInstance.configure(configuration);
69+
70+
List<Diagnostic> diagnostics = getDiagnostics();
71+
assertThat(diagnostics).isEmpty();
72+
73+
}
74+
75+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// при наличии в списке зарезервированного имени перечисления ВидГруппыФормы должен сработать тест
2+
3+
Процедура Тест1(ВидГруппыФормы) // здесь должен сработать тест
4+
5+
А = ВидГруппыФормы.ОбычнаяГруппа;
6+
7+
КонецПроцедуры

0 commit comments

Comments
 (0)