Skip to content

Commit b174b48

Browse files
authored
Merge pull request #3210 from artbear/magic-number
[MOD] MagicNumber - ловим магические числа везде, в т.ч. и при передаче параметров - ГОТОВО
2 parents 8afa0bb + 9c820db commit b174b48

File tree

3 files changed

+81
-50
lines changed

3 files changed

+81
-50
lines changed

src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicNumberDiagnostic.java

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,14 @@
2828
import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticType;
2929
import com.github._1c_syntax.bsl.languageserver.utils.DiagnosticHelper;
3030
import com.github._1c_syntax.bsl.parser.BSLParser;
31-
import org.antlr.v4.runtime.ParserRuleContext;
31+
import com.github._1c_syntax.bsl.parser.BSLParserRuleContext;
3232
import org.antlr.v4.runtime.tree.ParseTree;
3333

3434
import java.util.ArrayList;
3535
import java.util.Arrays;
3636
import java.util.List;
3737
import java.util.Map;
38+
import java.util.Optional;
3839

3940
@DiagnosticMetadata(
4041
type = DiagnosticType.CODE_SMELL,
@@ -49,7 +50,6 @@ public class MagicNumberDiagnostic extends AbstractVisitorDiagnostic {
4950
private static final String DEFAULT_AUTHORIZED_NUMBERS = "-1,0,1";
5051
private static final boolean DEFAULT_ALLOW_MAGIC_NUMBER = true;
5152

52-
5353
@DiagnosticParameter(
5454
type = String.class,
5555
defaultValue = "" + DEFAULT_AUTHORIZED_NUMBERS
@@ -75,37 +75,54 @@ public void configure(Map<String, Object> configuration) {
7575
}
7676
}
7777

78+
private static Optional<BSLParser.ExpressionContext> getExpression(BSLParserRuleContext ctx) {
79+
return Optional.of(ctx)
80+
.filter(context -> context.getChildCount() == 1)
81+
.map(BSLParserRuleContext::getParent)
82+
.filter(context -> context.getChildCount() == 1)
83+
.map(BSLParserRuleContext::getParent)
84+
.filter(BSLParser.ExpressionContext.class::isInstance)
85+
.map(BSLParser.ExpressionContext.class::cast);
86+
}
87+
88+
private static boolean isNumericExpression(BSLParser.ExpressionContext expression) {
89+
return (expression.getChildCount() <= 1);
90+
}
91+
92+
private static boolean insideCallParam(BSLParser.ExpressionContext expression) {
93+
return expression.getParent() instanceof BSLParser.CallParamContext;
94+
}
95+
7896
@Override
7997
public ParseTree visitNumeric(BSLParser.NumericContext ctx) {
8098
String checked = ctx.getText();
8199

82-
if (checked != null && !isExcluded(checked)) {
83-
ParserRuleContext expression = ctx.getParent().getParent().getParent();
84-
if (expression instanceof BSLParser.ExpressionContext
85-
&& (!isNumericExpression((BSLParser.ExpressionContext) expression)
86-
|| mayBeNumberAccess((BSLParser.ExpressionContext) expression))) {
100+
if (checked != null && isAllowed(checked)) {
101+
final var parent = ctx.getParent();
102+
if (parent.getParent() instanceof BSLParser.DefaultValueContext || isWrongExpression(parent)) {
87103
diagnosticStorage.addDiagnostic(ctx.stop, info.getMessage(checked));
88104
}
89105
}
90-
91-
return ctx;
106+
return defaultResult();
92107
}
93108

94-
private boolean isExcluded(String s) {
109+
private boolean isAllowed(String s) {
95110
for (String elem : this.authorizedNumbers) {
96111
if (s.compareTo(elem) == 0) {
97-
return true;
112+
return false;
98113
}
99114
}
115+
return true;
116+
}
100117

101-
return false;
118+
private boolean isWrongExpression(BSLParserRuleContext numericContextParent) {
119+
return getExpression(numericContextParent)
120+
.filter((BSLParser.ExpressionContext expression) ->
121+
(!isNumericExpression(expression) || mayBeNumberAccess(expression) || insideCallParam(expression)))
122+
.isPresent();
102123
}
103124

104125
private boolean mayBeNumberAccess(BSLParser.ExpressionContext expression) {
105126
return !allowMagicIndexes && expression.getParent() instanceof BSLParser.AccessIndexContext;
106127
}
107-
108-
private static boolean isNumericExpression(BSLParser.ExpressionContext expression) {
109-
return (expression.getChildCount() <= 1);
110-
}
111128
}

src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicNumberDiagnosticTest.java

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,20 @@ void runTest() {
4242
List<Diagnostic> diagnostics = getDiagnostics();
4343

4444
// then
45-
assertThat(diagnostics).hasSize(7);
45+
assertThat(diagnostics).hasSize(12);
4646
assertThat(diagnostics, true)
47-
.hasRange(3, 18, 3, 20)
48-
.hasRange(3, 23, 3, 25)
49-
.hasRange(7, 31, 7, 33)
50-
.hasRange(11, 20, 11, 21)
51-
.hasRange(20, 21, 20, 23)
52-
.hasRange(23, 24, 23, 26)
53-
.hasRange(27, 34, 27, 35);
47+
.hasRange(3, 18, 20)
48+
.hasRange(3, 23, 25)
49+
.hasRange(7, 31, 33)
50+
.hasRange(11, 20, 21)
51+
.hasRange(20, 21, 23)
52+
.hasRange(23, 24, 26)
53+
.hasRange(27, 34, 35)
54+
.hasRange(33, 37, 38)
55+
.hasRange(34, 37, 38)
56+
.hasRange(36, 87, 88)
57+
.hasRange(37, 55, 56)
58+
.hasRange(41, 16, 19);
5459
}
5560

5661
@Test
@@ -64,12 +69,17 @@ void testConfigure() {
6469
List<Diagnostic> diagnostics = getDiagnostics();
6570

6671
// then
67-
assertThat(diagnostics).hasSize(4);
72+
assertThat(diagnostics).hasSize(9);
6873
assertThat(diagnostics, true)
69-
.hasRange(7, 31, 7, 33)
70-
.hasRange(11, 20, 11, 21)
71-
.hasRange(20, 21, 20, 23)
72-
.hasRange(23, 24, 23, 26);
74+
.hasRange(7, 31, 33)
75+
.hasRange(11, 20, 21)
76+
.hasRange(20, 21, 23)
77+
.hasRange(23, 24, 26)
78+
.hasRange(33, 37, 38)
79+
.hasRange(34, 37, 38)
80+
.hasRange(36, 87, 88)
81+
.hasRange(37, 55, 56)
82+
.hasRange(41, 16, 19);
7383
}
7484

7585
@Test
@@ -83,17 +93,22 @@ void testIndexes() {
8393
List<Diagnostic> diagnostics = getDiagnostics();
8494

8595
// then
86-
assertThat(diagnostics).hasSize(9);
96+
assertThat(diagnostics).hasSize(14);
8797
assertThat(diagnostics, true)
88-
.hasRange(3, 18, 3, 20)
89-
.hasRange(3, 23, 3, 25)
90-
.hasRange(7, 31, 7, 33)
91-
.hasRange(11, 20, 11, 21)
92-
.hasRange(20, 21, 20, 23)
93-
.hasRange(23, 24, 23, 26)
94-
.hasRange(27, 34, 27, 35)
95-
.hasRange(53, 32, 53, 34)
96-
.hasRange(54, 18, 54, 20);
98+
.hasRange(3, 18, 20)
99+
.hasRange(3, 23, 25)
100+
.hasRange(7, 31, 33)
101+
.hasRange(11, 20, 21)
102+
.hasRange(20, 21, 23)
103+
.hasRange(23, 24, 26)
104+
.hasRange(27, 34, 35)
105+
.hasRange(33, 37, 38)
106+
.hasRange(34, 37, 38)
107+
.hasRange(36, 87, 88)
108+
.hasRange(37, 55, 56)
109+
.hasRange(41, 16, 19)
110+
.hasRange(52, 32, 34)
111+
.hasRange(53, 18, 20);
97112
}
98113

99114
}

src/test/resources/diagnostics/MagicNumberDiagnostic.bsl

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Процедура ПроверкаЧисел()
22

33
ПонятнаяПеременная = 6; // Нет ошибки
4-
СекундВЧасе = 60 * 60; // Ошибкат на двух числах
4+
СекундВЧасе = 60 * 60; // Ошибка на двух числах
55

66
Если ТекущаяДатаИВремя > СекундВЧасе Тогда // Нет ошибки
77

@@ -25,22 +25,21 @@
2525

2626
КонецЕсли;
2727

28-
ЭтоВоскресенье = ДеньНедели = 7; // Тут ошибка, хоть и вглядит нормально.
28+
ЭтоВоскресенье = ДеньНедели = 7; // Тут ошибка, хоть и выглядит нормально.
2929
ДеньНеделиВоскресенье = 7;
3030
ЭтоВоскресенье = ДеньНедели = ДеньНеделиВоскресенье; // А вот тут уже ошибки нет
3131

32-
// Далеше без ошибок
3332
ПроверочноеПеречисление = Новый Массив;
34-
ПроверочноеПеречисление.Добавить(1);
35-
ПроверочноеПеречисление.Добавить(2);
36-
ПроверочноеПеречисление.Добавить(3);
33+
ПроверочноеПеречисление.Добавить(1); // Нет ошибки из-за исключения
34+
ПроверочноеПеречисление.Добавить(2); // ошибка
35+
ПроверочноеПеречисление.Добавить(3); // ошибка
3736

38-
ПроверочнаяСтруктура = Новый Структура("Авто,ПростойВариант,СложныйВариант", 0, 1, 2);
39-
ПроверочнаяСтруктура.Добавить("ЭкспертныйВариант", 3);
37+
ПроверочнаяСтруктура = Новый Структура("Авто,ПростойВариант,СложныйВариант", 0, 1, 2); // ошибка только на 2
38+
ПроверочнаяСтруктура.Добавить("ЭкспертныйВариант", 3); // ошибка
4039

4140
КонецПроцедуры
4241

43-
Процедура А(А = 566)
42+
Процедура А(А = 566) // пропущенная ошибка
4443

4544
КонецПроцедуры
4645

@@ -51,6 +50,6 @@
5150
КонецФункции
5251

5352
Процедура Индексы()
54-
Индекс1 = Коллекция.Индексы[20];
55-
Метод(Индексы[21])
53+
Индекс1 = Коллекция.Индексы[20]; // замечание при allowMagicIndexes = false
54+
Метод(Индексы[21]) // замечание при allowMagicIndexes = false
5655
КонецПроцедуры

0 commit comments

Comments
 (0)