Skip to content

Commit e33797c

Browse files
committed
GH-2 Indetation size rewriting - created indentaion block
1 parent 5c8a705 commit e33797c

File tree

8 files changed

+133
-23
lines changed

8 files changed

+133
-23
lines changed

src/main/java/io/mpolivaha/maven/plugin/editorconfig/common/ByteArrayLine.java

+27
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,16 @@
77
import io.mpolivaha.maven.plugin.editorconfig.model.EndOfLine;
88
import java.util.ArrayList;
99
import java.util.Arrays;
10+
import java.util.Set;
1011

1112
public class ByteArrayLine {
1213

14+
private static final Set<Byte> NEW_CODE_BLOCK_START = Set.of(
15+
(byte) '{', // code block
16+
(byte) '(', // function definition, function call etc
17+
(byte) '[' // array declaration
18+
);
19+
1320
private final byte[] line;
1421
private final int eolStartsIndex;
1522
private final EndOfLine endOfLine;
@@ -80,6 +87,26 @@ public int getIndentInColumns(Integer softTabsForOneHard) {
8087
return flatten.lengthWithEoL();
8188
}
8289

90+
public boolean startsNewCodeBlock() {
91+
byte[] contentWithEol = getContentWithEol();
92+
93+
Byte previous = null;
94+
95+
for (int i = contentWithEol.length - 2; i >= 0; i--) {
96+
byte current = contentWithEol[i];
97+
if (NEW_CODE_BLOCK_START.contains(current)) {
98+
return true;
99+
} else if (current == '>' && previous != null && previous == '-') {
100+
return true;
101+
} else if (current != ' ' && current != '\t') {
102+
return false;
103+
}
104+
previous = current;
105+
}
106+
107+
return false;
108+
}
109+
83110
/**
84111
* Flattens the line, which means that it replaces all the hard tabs (\t) with
85112
* the corresponding amount of the soft tabs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.mpolivaha.maven.plugin.editorconfig.common;
2+
3+
/**
4+
* @param indentLevel level of indentation is used for this block
5+
*/
6+
public record IndentationBlock(
7+
int indentLevel
8+
) {
9+
10+
public static IndentationBlock root() {
11+
return new IndentationBlock(0);
12+
}
13+
14+
public IndentationBlock next(int indentSize) {
15+
return new IndentationBlock(this.indentLevel + indentSize);
16+
}
17+
}

src/main/java/io/mpolivaha/maven/plugin/editorconfig/model/EndOfLine.java

+4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ public static Optional<EndOfLine> from(String symbol) {
2828
return Optional.empty();
2929
}
3030

31+
public String getPrintableSpecMarker() {
32+
return this.compareTo(EndOfLine.EOF) != 0 ? specMarker : "\\0 (END_OF_FILE)";
33+
}
34+
3135
public boolean isSingleCharacter() {
3236
return !this.equals(CARRIAGE_RERUN_LINE_FEED);
3337
}

src/main/java/io/mpolivaha/maven/plugin/editorconfig/verifiers/impl/EndOfLineOptionVerifier.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ protected void forEachLine(ByteArrayLine line, int lineNumber, EndOfLine optionV
3131
// here, we're potentially checking the last line which might be EOF
3232
// In this case, we'll 100% will fail the build, and I think it is the
3333
// right way to do this since the last line of the file is still a POSIX line
34-
result.addErrorMessage(ERROR_MESSAGE_PRODUCER.apply(lineNumber, optionValue.getEolSymbol(), line.getEndOfLine().getEolSymbol()));
34+
result.addErrorMessage(ERROR_MESSAGE_PRODUCER.apply(lineNumber, optionValue.getPrintableSpecMarker(), line.getEndOfLine().getPrintableSpecMarker()));
3535
}
3636
}
3737
}

src/main/java/io/mpolivaha/maven/plugin/editorconfig/verifiers/impl/IndentationSizeOptionVerifier.java

+11-21
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import io.mpolivaha.maven.plugin.editorconfig.Editorconfig.Section;
44
import io.mpolivaha.maven.plugin.editorconfig.assertions.Assert;
55
import io.mpolivaha.maven.plugin.editorconfig.common.ByteArrayLine;
6+
import io.mpolivaha.maven.plugin.editorconfig.common.IndentationBlock;
67
import io.mpolivaha.maven.plugin.editorconfig.model.IndentationStyle;
78
import io.mpolivaha.maven.plugin.editorconfig.model.Option;
89
import io.mpolivaha.maven.plugin.editorconfig.model.TrueFalse;
@@ -22,6 +23,11 @@ public class IndentationSizeOptionVerifier extends SpecOptionVerifier<Integer> {
2223

2324
private static final String PREVIOUS_LINE_KEY = "PREVIOUS_LINE_KEY";
2425

26+
/**
27+
* The indentation block that is applicable for the given line
28+
*/
29+
private static final String INDENTATION_BLOCK = "INDENTATION_BLOCK";
30+
2531
public IndentationSizeOptionVerifier() {
2632
super(Option.IDENT_SIZE);
2733
}
@@ -34,28 +40,12 @@ protected void onInit(Section section) {
3440
@Override
3541
protected void forEachLine(ByteArrayLine line, int lineNumber, Integer optionValue, OptionValidationResult result, Map<String, Object> executionContext) {
3642
Assert.notNull(section, "The section cannot be null at this point");
43+
var indentationBlock = (IndentationBlock) executionContext.getOrDefault(INDENTATION_BLOCK, IndentationBlock.root());
3744

38-
ByteArrayLine previous;
39-
if ((previous = (ByteArrayLine) executionContext.get(PREVIOUS_LINE_KEY)) == null) {
40-
executionContext.put(PREVIOUS_LINE_KEY, line);
41-
return;
42-
}
43-
44-
// TODO: Here, we reclaculate the indent of previous line, which can in fact be avoided
45-
int previousIndent = previous.getIndentInColumns(section.getTabWidth());
46-
int thisIndent = line.getIndentInColumns(section.getTabWidth());
47-
48-
if (previousIndent != thisIndent) {
49-
int indentLevel = Math.abs(previousIndent - thisIndent);
50-
if (indentLevel != optionValue) {
51-
result.addErrorMessage(
52-
"The indentation level between lines %d and %d differs from the configured level of indentation. Required: %d, Actual : %d"
53-
.formatted(lineNumber - 1, lineNumber, optionValue, indentLevel)
54-
);
55-
}
56-
}
57-
58-
executionContext.put(PREVIOUS_LINE_KEY, line);
45+
executionContext.put(
46+
PREVIOUS_LINE_KEY,
47+
line.startsNewCodeBlock() ? indentationBlock.next(optionValue) : indentationBlock
48+
);
5949
}
6050

6151
@Override

src/test/java/io/mpolivaha/maven/plugin/editorconfig/common/ByteArrayLineTest.java

+35
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
package io.mpolivaha.maven.plugin.editorconfig.common;
22

33
import io.mpolivaha.maven.plugin.editorconfig.model.EndOfLine;
4+
import java.nio.charset.StandardCharsets;
5+
import java.util.stream.Stream;
46
import org.assertj.core.api.Assertions;
57
import org.junit.jupiter.api.Test;
8+
import org.junit.jupiter.params.ParameterizedTest;
9+
import org.junit.jupiter.params.provider.Arguments;
10+
import org.junit.jupiter.params.provider.MethodSource;
611

712
/**
813
* Unit tests for {@link ByteArrayLine}
@@ -136,4 +141,34 @@ void test_getIndentInColumns_mixedIndentation() {
136141
// then.
137142
Assertions.assertThat(sut.getIndentInColumns(2)).isEqualTo(6);
138143
}
144+
145+
@ParameterizedTest
146+
@MethodSource("test_startsNewCodeBlock_args")
147+
void test_startsNewCodeBlock(String string, boolean expectedStartsNewCodeBlock) {
148+
149+
// when.
150+
boolean startsNewCodeBlock = new ByteArrayLine(
151+
string.getBytes(StandardCharsets.US_ASCII),
152+
string.length() - 1,
153+
EndOfLine.LINE_FEED
154+
).startsNewCodeBlock();
155+
156+
// then.
157+
Assertions.assertThat(startsNewCodeBlock).isEqualTo(expectedStartsNewCodeBlock);
158+
}
159+
160+
161+
static Stream<Arguments> test_startsNewCodeBlock_args() {
162+
return Stream.of(
163+
Arguments.of("package com.example;", false),
164+
Arguments.of("public static void main() {\n", true),
165+
Arguments.of("public static void main() { \n", true),
166+
Arguments.of("((CastToSomething) other).invoke (\n", true),
167+
Arguments.of("if (something()) \n", false),
168+
Arguments.of("[\n", true),
169+
Arguments.of("[1, 2, 3].length", false),
170+
Arguments.of("if (something()) \n", false),
171+
Arguments.of("if (something()) {\n", true)
172+
);
173+
}
139174
}

src/test/java/io/mpolivaha/maven/plugin/editorconfig/verifiers/impl/EndOfLineOptionVerifierTest.java

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package io.mpolivaha.maven.plugin.editorconfig.verifiers.impl;
22

33
import io.mpolivaha.maven.plugin.editorconfig.model.EndOfLine;
4-
import io.mpolivaha.maven.plugin.editorconfig.model.Option;
54
import io.mpolivaha.maven.plugin.editorconfig.verifiers.OptionValidationResult;
65
import java.util.stream.Stream;
76
import org.assertj.core.api.Assertions;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package io.mpolivaha.maven.plugin.editorconfig.verifiers.impl;
2+
3+
import io.mpolivaha.maven.plugin.editorconfig.common.CachingInputStream;
4+
import io.mpolivaha.maven.plugin.editorconfig.model.Charset;
5+
import io.mpolivaha.maven.plugin.editorconfig.model.IndentationStyle;
6+
import io.mpolivaha.maven.plugin.editorconfig.verifiers.OptionValidationResult;
7+
import java.nio.file.Paths;
8+
import java.util.stream.Stream;
9+
import org.assertj.core.api.Assertions;
10+
import org.junit.jupiter.params.ParameterizedTest;
11+
import org.junit.jupiter.params.provider.Arguments;
12+
import org.junit.jupiter.params.provider.MethodSource;
13+
14+
class IndentationStyleOptionVerifierTest {
15+
16+
private final IndentationStyleOptionVerifier subject = new IndentationStyleOptionVerifier();
17+
18+
@ParameterizedTest
19+
@MethodSource(value = {"arguments"})
20+
void testCharsetOptionVerifier(String sourceCodeFile, IndentationStyle indentationStyle, boolean noErrors) throws Exception {
21+
OptionValidationResult check = subject.check(
22+
new CachingInputStream(
23+
Paths.get(ClassLoader
24+
.getSystemClassLoader()
25+
.getResource(sourceCodeFile).toURI()).toFile()
26+
),
27+
SectionTestUtils.testSection(sectionBuilder -> sectionBuilder.indentationStyle(indentationStyle))
28+
);
29+
30+
Assertions.assertThat(check.noErrors()).isEqualTo(noErrors);
31+
}
32+
33+
static Stream<Arguments> arguments() {
34+
return Stream.of(
35+
Arguments.of("sources/charset/TestJavaClass_LATIN1.java", IndentationStyle.TAB, true)
36+
);
37+
}
38+
}

0 commit comments

Comments
 (0)