Skip to content

Commit 32c8a86

Browse files
committed
Account for !--- doc splitter for properties validation
1 parent 4aa4400 commit 32c8a86

File tree

10 files changed

+205
-60
lines changed

10 files changed

+205
-60
lines changed

headless-services/commons/java-properties/src/main/java/org/springframework/ide/vscode/java/properties/parser/PropertiesAst.java

+6-17
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2016 Pivotal, Inc.
2+
* Copyright (c) 2016, 2024 Pivotal, Inc.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -11,8 +11,6 @@
1111
package org.springframework.ide.vscode.java.properties.parser;
1212

1313
import java.util.List;
14-
import java.util.function.Predicate;
15-
import java.util.stream.Collectors;
1614

1715
/**
1816
* Very basic AST for Java Properties to keep comments and key value pairs
@@ -36,21 +34,12 @@ public List<Node> getAllNodes() {
3634
return nodes;
3735
}
3836

39-
public List<Node> getNodes(Predicate<Node> test) {
40-
return nodes.stream().filter(test).collect(Collectors.toList());
37+
public List<KeyValuePair> getPropertyValuePairs() {
38+
return nodes.stream().filter(KeyValuePair.class::isInstance).map(KeyValuePair.class::cast).toList();
4139
}
42-
43-
/**
44-
* Retrieves AST nodes of specific type
45-
* @param clazz Type of AST nodes
46-
* @return List of AST nodes of specific type sorted by line number
47-
*/
48-
@SuppressWarnings("unchecked")
49-
public <T> List<T> getNodes(Class<T> clazz) {
50-
List<Node> l = nodes.stream().filter(line -> {
51-
return clazz.isAssignableFrom(line.getClass());
52-
}).collect(Collectors.toList());
53-
return (List<T>) l;
40+
41+
public List<Comment> getComments() {
42+
return nodes.stream().filter(Comment.class::isInstance).map(Comment.class::cast).toList();
5443
}
5544

5645
/**

headless-services/commons/java-properties/src/test/java/org/springframework/ide/vscode/java/properties/parser/test/PropertiesAntlrParserTest.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2016 Pivotal, Inc.
2+
* Copyright (c) 2016, 2024 Pivotal, Inc.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -35,7 +35,7 @@ private void testCommentLine(String text, String expectedComment) {
3535
assertTrue(results.problems.isEmpty());
3636
assertEquals(1, results.ast.getAllNodes().size());
3737

38-
List<Comment> commentLines = results.ast.getNodes(Comment.class);
38+
List<Comment> commentLines = results.ast.getComments();
3939
assertEquals(1, commentLines.size());
4040

4141
Comment comment = commentLines.get(0);
@@ -52,7 +52,7 @@ private void testPropertyLine(String text,
5252
assertTrue(results.problems.isEmpty());
5353
assertEquals(1, results.ast.getAllNodes().size());
5454

55-
List<KeyValuePair> propertyLines = results.ast.getNodes(KeyValuePair.class);
55+
List<KeyValuePair> propertyLines = results.ast.getPropertyValuePairs();
5656
assertEquals(1, propertyLines.size());
5757

5858
KeyValuePair line = propertyLines.get(0);
@@ -197,7 +197,7 @@ public void testMultipleSyntaxErrors() throws Exception {
197197
assertTrue(results.problems.isEmpty());
198198
// One property line recorded. With key and empty value
199199
assertEquals(3, results.ast.getAllNodes().size());
200-
List<KeyValuePair> lines = results.ast.getNodes(KeyValuePair.class);
200+
List<KeyValuePair> lines = results.ast.getPropertyValuePairs();
201201
assertEquals(3, lines.size());
202202

203203
// Test valid part

headless-services/commons/java-properties/src/test/java/org/springframework/ide/vscode/java/properties/parser/test/PropertiesAstTest.java

+13-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2016-2017 Pivotal, Inc.
2+
* Copyright (c) 2016, 2024 Pivotal, Inc.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -36,8 +36,8 @@ public void testLines1() throws Exception {
3636
assertTrue(results.syntaxErrors.isEmpty());
3737
assertTrue(results.problems.isEmpty());
3838
assertEquals(4, results.ast.getAllNodes().size());
39-
assertEquals(1, results.ast.getNodes(Comment.class).size());
40-
assertEquals(3, results.ast.getNodes(EmptyLine.class).size());
39+
assertEquals(1, results.ast.getComments().size());
40+
// assertEquals(3, results.ast.getNodes(EmptyLine.class).size());
4141
}
4242

4343
@Test
@@ -46,8 +46,8 @@ public void testLines2() throws Exception {
4646
assertTrue(results.syntaxErrors.isEmpty());
4747
assertTrue(results.problems.isEmpty());
4848
assertEquals(5, results.ast.getAllNodes().size());
49-
assertEquals(1, results.ast.getNodes(Comment.class).size());
50-
assertEquals(4, results.ast.getNodes(EmptyLine.class).size());
49+
assertEquals(1, results.ast.getComments().size());
50+
// assertEquals(4, results.ast.getNodes(EmptyLine.class).size());
5151
}
5252

5353
@Test
@@ -56,26 +56,26 @@ public void testLines3() throws Exception {
5656
assertTrue(results.syntaxErrors.isEmpty());
5757
assertTrue(results.problems.isEmpty());
5858
assertEquals(5, results.ast.getAllNodes().size());
59-
assertEquals(1, results.ast.getNodes(Comment.class).size());
60-
assertEquals(1, results.ast.getNodes(KeyValuePair.class).size());
61-
assertEquals(3, results.ast.getNodes(EmptyLine.class).size());
59+
assertEquals(1, results.ast.getComments().size());
60+
assertEquals(1, results.ast.getPropertyValuePairs().size());
61+
// assertEquals(3, results.ast.getNodes(EmptyLine.class).size());
6262
}
6363

6464
@Test
6565
public void testLines4() throws Exception {
6666
ParseResults results = parser.parse("# Comment-1\n\nkey = value 1 \n# Comment-2");
6767
assertEquals(4, results.ast.getAllNodes().size());
68-
assertEquals(2, results.ast.getNodes(Comment.class).size());
69-
assertEquals(1, results.ast.getNodes(KeyValuePair.class).size());
70-
assertEquals(1, results.ast.getNodes(EmptyLine.class).size());
68+
assertEquals(2, results.ast.getComments().size());
69+
assertEquals(1, results.ast.getPropertyValuePairs().size());
70+
// assertEquals(1, results.ast.getNodes(EmptyLine.class).size());
7171
}
7272

7373
@Test
7474
public void testLines5() throws Exception {
7575
ParseResults results = parser.parse("#comment\nliquibase.enabled=\n#comment");
7676
assertEquals(3, results.ast.getAllNodes().size());
77-
assertEquals(2, results.ast.getNodes(Comment.class).size());
78-
assertEquals(1, results.ast.getNodes(KeyValuePair.class).size());
77+
assertEquals(2, results.ast.getComments().size());
78+
assertEquals(1, results.ast.getPropertyValuePairs().size());
7979
}
8080

8181
@Test

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/factories/SpringFactoriesReconcileEngine.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2022 VMware, Inc.
2+
* Copyright (c) 2022, 2024 VMware, Inc.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -63,7 +63,7 @@ public void reconcile(IDocument doc, IProblemCollector problemCollector) {
6363
try {
6464
PropertiesAst ast = parser.parse(doc.get()).ast;
6565
if (ast != null) {
66-
for (KeyValuePair pair : ast.getNodes(KeyValuePair.class)) {
66+
for (KeyValuePair pair : ast.getPropertyValuePairs()) {
6767
String key = pair.getKey().decode().trim();
6868
KeyValuePairReconciler r = keyValuePairReconcilers.get(key);
6969
if (r != null) {

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/jpa/queries/NamedQueryPropertiesReconcileEngine.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public void reconcile(IDocument doc, IProblemCollector problemCollector) {
4343

4444
AntlrParser parser = new AntlrParser();
4545
ParseResults parseResults = parser.parse(doc.get());
46-
for (KeyValuePair pair : parseResults.ast.getNodes(KeyValuePair.class)) {
46+
for (KeyValuePair pair : parseResults.ast.getPropertyValuePairs()) {
4747
Value value = pair.getValue();
4848
reconciler.reconcile(value.decode(), value.getOffset(), problemCollector);
4949
}

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/jpa/queries/QueryPropertiesSemanticTokensHandler.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public List<SemanticTokenData> semanticTokensFull(TextDocument doc, CancelChecke
7373
AntlrParser propertiesParser = new AntlrParser();
7474
ParseResults result = propertiesParser.parse(doc.get());
7575
List<SemanticTokenData> data = new ArrayList<>();
76-
for (PropertiesAst.KeyValuePair node : result.ast.getNodes(PropertiesAst.KeyValuePair.class)) {
76+
for (PropertiesAst.KeyValuePair node : result.ast.getPropertyValuePairs()) {
7777
Value value = node.getValue();
7878
if (value != null) {
7979
data.addAll(tokensProvider.computeTokens(value.decode(), value.getOffset()));

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringFactoriesIndexer.java

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2023 VMware, Inc.
2+
* Copyright (c) 2023, 2024 VMware, Inc.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -52,7 +52,6 @@
5252
import org.springframework.ide.vscode.java.properties.antlr.parser.AntlrParser;
5353
import org.springframework.ide.vscode.java.properties.parser.PropertiesAst;
5454
import org.springframework.ide.vscode.java.properties.parser.PropertiesAst.KeyValuePair;
55-
import org.springframework.ide.vscode.java.properties.parser.PropertiesAst.Node;
5655

5756
import com.google.common.collect.ImmutableList;
5857

@@ -109,8 +108,7 @@ private List<EnhancedSymbolInformation> computeSymbols(String docURI, String con
109108
ImmutableList.Builder<EnhancedSymbolInformation> symbols = ImmutableList.builder();
110109
PropertiesAst ast = new AntlrParser().parse(content).ast;
111110
if (ast != null) {
112-
for (Node n : ast.getNodes(KeyValuePair.class::isInstance)) {
113-
KeyValuePair pair = (KeyValuePair) n;
111+
for (KeyValuePair pair : ast.getPropertyValuePairs()) {
114112
String key = pair.getKey().decode();
115113

116114
if (KEYS.contains(key)) {

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/value/ValuePropertyReferencesProvider.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ static List<Location> findReferencesInPropertiesFile(File file, String propertyK
285285
ParseResults parseResults = parser.parse(fileContent);
286286

287287
if (parseResults != null && parseResults.ast != null) {
288-
parseResults.ast.getNodes(KeyValuePair.class).forEach(pair -> {
288+
parseResults.ast.getPropertyValuePairs().forEach(pair -> {
289289
if (pair.getKey() != null && pair.getKey().decode().equals(propertyKey)) {
290290
TextDocument doc = new TextDocument(file.toURI().toASCIIString(), null);
291291
doc.setText(fileContent);

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/reconcile/SpringPropertiesReconcileEngine.java

+52-15
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2014, 2019 Pivotal, Inc.
2+
* Copyright (c) 2014, 2024 Pivotal, Inc.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -16,6 +16,7 @@
1616
import static org.springframework.ide.vscode.boot.properties.reconcile.SpringPropertyProblem.problem;
1717
import static org.springframework.ide.vscode.commons.util.StringUtil.commonPrefix;
1818

19+
import java.util.List;
1920
import java.util.regex.Pattern;
2021

2122
import org.eclipse.lsp4j.TextDocumentIdentifier;
@@ -29,10 +30,10 @@
2930
import org.springframework.ide.vscode.boot.metadata.types.TypeParser;
3031
import org.springframework.ide.vscode.boot.metadata.types.TypeUtil;
3132
import org.springframework.ide.vscode.boot.metadata.types.TypeUtilProvider;
32-
import org.springframework.ide.vscode.boot.properties.quickfix.DeprecatedPropertyData;
33-
import org.springframework.ide.vscode.boot.properties.quickfix.MissingPropertyData;
3433
import org.springframework.ide.vscode.boot.properties.quickfix.AppPropertiesQuickFixes;
3534
import org.springframework.ide.vscode.boot.properties.quickfix.CommonQuickfixes;
35+
import org.springframework.ide.vscode.boot.properties.quickfix.DeprecatedPropertyData;
36+
import org.springframework.ide.vscode.boot.properties.quickfix.MissingPropertyData;
3637
import org.springframework.ide.vscode.commons.languageserver.quickfix.Quickfix.QuickfixData;
3738
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixType;
3839
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
@@ -47,8 +48,8 @@
4748
import org.springframework.ide.vscode.java.properties.antlr.parser.AntlrParser;
4849
import org.springframework.ide.vscode.java.properties.parser.ParseResults;
4950
import org.springframework.ide.vscode.java.properties.parser.Parser;
50-
import org.springframework.ide.vscode.java.properties.parser.PropertiesAst.KeyValuePair;
5151
import org.springframework.ide.vscode.java.properties.parser.PropertiesAst.Comment;
52+
import org.springframework.ide.vscode.java.properties.parser.PropertiesAst.KeyValuePair;
5253
import org.springframework.ide.vscode.java.properties.parser.PropertiesAst.Node;
5354
import org.springframework.ide.vscode.java.properties.parser.PropertiesFileEscapes;
5455

@@ -68,9 +69,9 @@ public class SpringPropertiesReconcileEngine implements IReconcileEngine {
6869
/**
6970
* Regexp that matches a ',' surrounded by whitespace, including escaped whitespace / newlines
7071
*/
71-
private static final Pattern COMMA = Pattern.compile(
72-
"(\\s|\\\\\\s)*,(\\s|\\\\\\s)*"
73-
);
72+
// private static final Pattern COMMA = Pattern.compile(
73+
// "(\\s|\\\\\\s)*,(\\s|\\\\\\s)*"
74+
// );
7475

7576
private static final Pattern SPACES = Pattern.compile(
7677
"(\\s|\\\\\\s)*"
@@ -108,11 +109,13 @@ public void reconcile(IDocument doc, IProblemCollector problemCollector) {
108109
// some problem putting information about properties into the index.
109110
return;
110111
}
111-
112-
results.ast.getNodes(n -> n instanceof KeyValuePair || n instanceof Comment).forEach(node -> {
112+
113+
List<Node> nodes = results.ast.getAllNodes();
114+
for (int i = 0; i < results.ast.getAllNodes().size(); i++) {
115+
Node node = nodes.get(i);
113116
try {
114117
if (node instanceof Comment) {
115-
if (isDocumentMarker(doc, (Comment)node)) {
118+
if (isDocumentMarker(doc, nodes, i)) {
116119
duplicateNameChecker.startNewSubDocument();
117120
}
118121
} else if (node instanceof KeyValuePair) {
@@ -144,18 +147,52 @@ public void reconcile(IDocument doc, IProblemCollector problemCollector) {
144147
} catch (Exception e) {
145148
log.error("", e);
146149
}
147-
});
150+
}
151+
148152
} catch (Throwable e2) {
149153
log.error("", e2);
150154
} finally {
151155
problemCollector.endCollecting();
152156
}
153157
}
154158

155-
private boolean isDocumentMarker(IDocument doc, Comment node) {
156-
DocumentRegion region = createRegion(doc, node).trimEnd();
157-
String t = region.toString();
158-
return t.equals("#---") && region.isAtStartOfLine();
159+
private boolean isDocumentMarker(IDocument doc, List<Node> nodes, int idx) {
160+
Node node = nodes.get(idx);
161+
if (node instanceof Comment) {
162+
DocumentRegion region = createRegion(doc, node).trimEnd();
163+
String t = region.toString();
164+
if (region.isAtStartOfLine()) {
165+
switch (t) {
166+
case "#---":
167+
// Check if next line starts with the same comment prefix. If yes then not a doc splitter
168+
if (isNextLineCommentWithPrefix(doc, nodes, idx, "#")) {
169+
return false;
170+
}
171+
return true;
172+
case "!---":
173+
// Check if next line starts with the same comment prefix. If yes then not a doc splitter
174+
if (isNextLineCommentWithPrefix(doc, nodes, idx, "!")) {
175+
return false;
176+
}
177+
return true;
178+
}
179+
180+
}
181+
}
182+
return false;
183+
}
184+
185+
private boolean isNextLineCommentWithPrefix(IDocument doc, List<Node> nodes, int idx, String prefix) {
186+
if (idx < nodes.size() - 1) {
187+
Node nextLine = nodes.get(idx + 1);
188+
if (nextLine instanceof Comment) {
189+
DocumentRegion nextRegion = createRegion(doc, nextLine).trimEnd();
190+
if (nextRegion.toString().startsWith(prefix)) {
191+
return true;
192+
}
193+
}
194+
}
195+
return false;
159196
}
160197

161198
protected SpringPropertyProblem problemDeprecated(DocumentRegion region, PropertyInfo property, QuickfixType fixType) {

0 commit comments

Comments
 (0)