Embedded code accounts for concatenated strings and escape chars
This commit is contained in:
@@ -13,19 +13,25 @@ package org.springframework.ide.vscode.commons.languageserver.semantic.tokens;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.text.IRegion;
|
||||
import org.springframework.ide.vscode.commons.util.text.Region;
|
||||
|
||||
public record SemanticTokenData(
|
||||
int start,
|
||||
int end,
|
||||
IRegion range,
|
||||
String type,
|
||||
String[] modifiers
|
||||
) implements Comparable<SemanticTokenData> {
|
||||
|
||||
public SemanticTokenData(int start, int end, String type, String[] modifiers) {
|
||||
this(new Region(start, end -start), type, modifiers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(SemanticTokenData o) {
|
||||
if (start == o.start) {
|
||||
return end - o.end;
|
||||
if (range.getOffset() == o.range().getOffset()) {
|
||||
return range.getLength() - o.range().getLength();
|
||||
}
|
||||
return start - o.start;
|
||||
return range.getOffset() - o.range().getOffset();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -33,7 +39,7 @@ public record SemanticTokenData(
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + Arrays.hashCode(modifiers);
|
||||
result = prime * result + Objects.hash(end, start, type);
|
||||
result = prime * result + Objects.hash(range, type);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -46,8 +52,16 @@ public record SemanticTokenData(
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
SemanticTokenData other = (SemanticTokenData) obj;
|
||||
return end == other.end && Arrays.equals(modifiers, other.modifiers) && start == other.start
|
||||
return range.getLength() == other.range.getLength() && Arrays.equals(modifiers, other.modifiers) && range.getOffset() == other.range().getOffset()
|
||||
&& Objects.equals(type, other.type);
|
||||
}
|
||||
|
||||
public int getStart() {
|
||||
return range.getStart();
|
||||
}
|
||||
|
||||
public int getEnd() {
|
||||
return range.getEnd();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,6 @@ public interface SemanticTokensDataProvider {
|
||||
|
||||
List<String> getTokenTypes();
|
||||
default List<String> getTypeModifiers() { return Collections.emptyList(); }
|
||||
List<SemanticTokenData> computeTokens(String text, int initialOffset);
|
||||
List<SemanticTokenData> computeTokens(String text);
|
||||
|
||||
}
|
||||
|
||||
@@ -52,11 +52,11 @@ public class SemanticTokensUtils {
|
||||
int previousLine = 0;
|
||||
int previousColumn = 0;
|
||||
for (SemanticTokenData tokenData : tokensData) {
|
||||
int currentLine = getLineNumber.apply(tokenData.start());
|
||||
int currentColumn = getColumnNumber.apply(tokenData.start());
|
||||
int currentLine = getLineNumber.apply(tokenData.getStart());
|
||||
int currentColumn = getColumnNumber.apply(tokenData.getStart());
|
||||
data.add(currentLine - previousLine);
|
||||
data.add(currentLine == previousLine ? currentColumn - previousColumn : currentColumn);
|
||||
data.add(tokenData.end() - tokenData.start());
|
||||
data.add(tokenData.getEnd() - tokenData.getStart());
|
||||
data.add(SemanticTokensUtils.getSemanticTokenTypeIndex(legend, tokenData.type()));
|
||||
data.add(SemanticTokensUtils.getSemanticTokenModifiersFlags(legend, tokenData.modifiers()));
|
||||
previousLine = currentLine;
|
||||
@@ -79,11 +79,11 @@ public class SemanticTokensUtils {
|
||||
int previousColumn = 0;
|
||||
for (SemanticTokenData tokenData : tokensData) {
|
||||
try {
|
||||
int currentLine = doc.getLineOfOffset(tokenData.start());
|
||||
int currentColumn = tokenData.start() - doc.getLineOffset(currentLine);
|
||||
int currentLine = doc.getLineOfOffset(tokenData.getStart());
|
||||
int currentColumn = tokenData.getStart() - doc.getLineOffset(currentLine);
|
||||
data.add(currentLine - previousLine);
|
||||
data.add(currentLine == previousLine ? currentColumn - previousColumn : currentColumn);
|
||||
data.add(tokenData.end() - tokenData.start());
|
||||
data.add(tokenData.getEnd() - tokenData.getStart());
|
||||
data.add(SemanticTokensUtils.getSemanticTokenTypeIndex(legend, tokenData.type()));
|
||||
data.add(SemanticTokensUtils.getSemanticTokenModifiersFlags(legend, tokenData.modifiers()));
|
||||
previousLine = currentLine;
|
||||
|
||||
@@ -18,5 +18,11 @@ public interface IRegion {
|
||||
|
||||
int getOffset();
|
||||
int getLength();
|
||||
default int getEnd() {
|
||||
return getOffset() + getLength();
|
||||
}
|
||||
default int getStart() {
|
||||
return getOffset();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1489,7 +1489,7 @@ InvalidUnterminatedUnicodeQuotedIdentifier: 'U' '&' InvalidUnterminatedQuotedIde
|
||||
|
||||
StringConstant: UnterminatedStringConstant '\'';
|
||||
|
||||
UnterminatedStringConstant: '\'' ('\'\'' | ~ '\'' | '\\\\\'' | '\\\'')*;
|
||||
UnterminatedStringConstant: '\'' ('\'\'' | ~ '\'' | '\\\'')*;
|
||||
// String Constants with C-style Escapes (4.1.2.2)
|
||||
|
||||
BeginEscapeStringConstant: 'E' '\'' -> more, pushMode (EscapeStringConstantMode);
|
||||
@@ -1625,7 +1625,6 @@ fragment EscapeStringText options {
|
||||
}:
|
||||
(
|
||||
'\\\''
|
||||
| '\'\'\''
|
||||
| '\\' (
|
||||
// two-digit hex escapes are still valid when treated as single-digit escapes
|
||||
'x' [0-9a-fA-F]
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,11 +14,11 @@ import java.util.Optional;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.ide.vscode.boot.java.data.jpa.queries.AntlrReconcilerWithSpel;
|
||||
import org.springframework.ide.vscode.boot.java.data.jpa.queries.HqlSemanticTokens;
|
||||
import org.springframework.ide.vscode.boot.java.data.jpa.queries.JpqlSemanticTokens;
|
||||
import org.springframework.ide.vscode.boot.java.data.jpa.queries.JpqlSupportState;
|
||||
import org.springframework.ide.vscode.boot.java.data.jpa.queries.QueryProblemType;
|
||||
import org.springframework.ide.vscode.boot.java.embadded.lang.AntlrReconcilerWithSpel;
|
||||
import org.springframework.ide.vscode.boot.java.spel.SpelReconciler;
|
||||
import org.springframework.ide.vscode.boot.java.spel.SpelSemanticTokens;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver;
|
||||
|
||||
@@ -14,6 +14,7 @@ import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.BitSet;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.antlr.v4.runtime.ANTLRErrorListener;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
@@ -35,6 +36,8 @@ import org.springframework.ide.vscode.boot.java.handlers.Reconciler;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblemImpl;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.IRegion;
|
||||
import org.springframework.ide.vscode.commons.util.text.Region;
|
||||
import org.springframework.ide.vscode.commons.util.text.linetracker.DefaultLineTracker;
|
||||
import org.springframework.ide.vscode.parser.cron.CronLexer;
|
||||
import org.springframework.ide.vscode.parser.cron.CronParser;
|
||||
@@ -62,7 +65,7 @@ public class CronReconciler implements Reconciler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reconcile(String text, int startPosition, IProblemCollector problemCollector) {
|
||||
public void reconcile(String text, Function<IRegion, IRegion> mapping, IProblemCollector problemCollector) {
|
||||
CronLexer lexer = new CronLexer(CharStreams.fromString(text));
|
||||
CommonTokenStream antlrTokens = new CommonTokenStream(lexer);
|
||||
CronParser parser = new CronParser(antlrTokens);
|
||||
@@ -117,7 +120,8 @@ public class CronReconciler implements Reconciler {
|
||||
if (message.startsWith("For input string:")) {
|
||||
markProblemsForNumberFormatException(ctx, message);
|
||||
} else {
|
||||
problemCollector.accept(new ReconcileProblemImpl(CronProblemType.FIELD, "CRON: %s".formatted(message), startPosition + ctx.getStart().getStartIndex(), ctx.getText().length()));
|
||||
IRegion r = mapping.apply(new Region(ctx.getStart().getStartIndex(), ctx.getText().length()));
|
||||
problemCollector.accept(new ReconcileProblemImpl(CronProblemType.FIELD, "CRON: %s".formatted(message), r.getOffset(), r.getLength()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,12 +136,14 @@ public class CronReconciler implements Reconciler {
|
||||
String problemText = message.substring(start + 1, end);
|
||||
int offset = text.indexOf(problemText);
|
||||
if (offset >= 0) {
|
||||
problemCollector.accept(new ReconcileProblemImpl(CronProblemType.FIELD, "CRON: Number expected", startPosition + ctx.getStart().getStartIndex() + offset, problemText.length()));
|
||||
IRegion r = mapping.apply(new Region(ctx.getStart().getStartIndex() + offset, problemText.length()));
|
||||
problemCollector.accept(new ReconcileProblemImpl(CronProblemType.FIELD, "CRON: Number expected", r.getOffset(), r.getLength()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
problemCollector.accept(new ReconcileProblemImpl(CronProblemType.FIELD, "CRON: %s".formatted(message), startPosition + ctx.getStart().getStartIndex(), ctx.getText().length()));
|
||||
IRegion r = mapping.apply(new Region(ctx.getStart().getStartIndex(), ctx.getText().length()));
|
||||
problemCollector.accept(new ReconcileProblemImpl(CronProblemType.FIELD, "CRON: %s".formatted(message), r.getOffset(), r.getLength()));
|
||||
}
|
||||
|
||||
|
||||
@@ -169,7 +175,8 @@ public class CronReconciler implements Reconciler {
|
||||
log.error("", e1);
|
||||
}
|
||||
}
|
||||
problemCollector.accept(new ReconcileProblemImpl(CronProblemType.SYNTAX, "CRON: " + msg, startPosition + offset, length));
|
||||
IRegion r = mapping.apply(new Region(offset, length));
|
||||
problemCollector.accept(new ReconcileProblemImpl(CronProblemType.SYNTAX, "CRON: " + msg, r.getOffset(), r.getLength()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -58,7 +58,7 @@ public class CronSemanticTokens implements SemanticTokensDataProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SemanticTokenData> computeTokens(String text, int initialOffset) {
|
||||
public List<SemanticTokenData> computeTokens(String text) {
|
||||
CronLexer lexer = new CronLexer(CharStreams.fromString(text));
|
||||
CommonTokenStream antlrTokens = new CommonTokenStream(lexer);
|
||||
CronParser parser = new CronParser(antlrTokens);
|
||||
@@ -157,8 +157,8 @@ public class CronSemanticTokens implements SemanticTokensDataProvider {
|
||||
parser.cronExpression();
|
||||
|
||||
tokens.addAll(semantics.entrySet().stream()
|
||||
.map(e -> new SemanticTokenData(e.getKey().getStartIndex() + initialOffset,
|
||||
e.getKey().getStartIndex() + e.getKey().getText().length() + initialOffset, e.getValue(),
|
||||
.map(e -> new SemanticTokenData(e.getKey().getStartIndex(),
|
||||
e.getKey().getStartIndex() + e.getKey().getText().length(), e.getValue(),
|
||||
new String[0]))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import java.net.URI;
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.eclipse.jdt.core.dom.NormalAnnotation;
|
||||
import org.springframework.ide.vscode.boot.java.data.jpa.queries.JdtQueryVisitorUtils.EmbeddedExpression;
|
||||
import org.springframework.ide.vscode.boot.java.embadded.lang.EmbeddedLanguageSnippet;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.JdtAstReconciler;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.SpringProjectUtil;
|
||||
@@ -46,9 +46,9 @@ public class JdtCronReconciler implements JdtAstReconciler {
|
||||
return new ASTVisitor() {
|
||||
@Override
|
||||
public boolean visit(NormalAnnotation node) {
|
||||
EmbeddedExpression e = JdtCronVisitorUtils.extractCron(node);
|
||||
EmbeddedLanguageSnippet e = JdtCronVisitorUtils.extractCron(node);
|
||||
if (e != null) {
|
||||
cronReconciler.reconcile(e.text(), e.offset(), problemCollector);
|
||||
cronReconciler.reconcile(e.getText(), e::toSingleJavaRange, problemCollector);
|
||||
}
|
||||
return super.visit(node);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.eclipse.jdt.core.dom.NormalAnnotation;
|
||||
import org.springframework.ide.vscode.boot.java.JdtSemanticTokensProvider;
|
||||
import org.springframework.ide.vscode.boot.java.data.jpa.queries.JdtQueryVisitorUtils.EmbeddedExpression;
|
||||
import org.springframework.ide.vscode.boot.java.embadded.lang.EmbeddedLanguageSnippet;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.SpringProjectUtil;
|
||||
import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokenData;
|
||||
@@ -56,9 +56,12 @@ public class JdtCronSemanticTokensProvider implements JdtSemanticTokensProvider
|
||||
|
||||
@Override
|
||||
public boolean visit(NormalAnnotation node) {
|
||||
EmbeddedExpression e = JdtCronVisitorUtils.extractCron(node);
|
||||
EmbeddedLanguageSnippet e = JdtCronVisitorUtils.extractCron(node);
|
||||
if (e != null) {
|
||||
tokensProvider.computeTokens(e.text(), e.offset()).forEach(collector::accept);
|
||||
tokensProvider.computeTokens(e.getText()).stream()
|
||||
.flatMap(td -> e.toJavaRanges(td.range()).stream().map(r -> new SemanticTokenData(r,
|
||||
td.type(), td.modifiers())))
|
||||
.forEach(collector::accept);
|
||||
}
|
||||
return super.visit(node);
|
||||
}
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.cron;
|
||||
|
||||
import static org.springframework.ide.vscode.boot.java.data.jpa.queries.JdtQueryVisitorUtils.extractEmbeddedExpression;
|
||||
|
||||
import org.eclipse.jdt.core.dom.Expression;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.MemberValuePair;
|
||||
@@ -19,13 +17,14 @@ import org.eclipse.jdt.core.dom.NormalAnnotation;
|
||||
import org.eclipse.jdt.core.dom.StringLiteral;
|
||||
import org.eclipse.jdt.core.dom.TextBlock;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.data.jpa.queries.JdtQueryVisitorUtils.EmbeddedExpression;
|
||||
import org.springframework.ide.vscode.boot.java.embadded.lang.EmbeddedLangAstUtils;
|
||||
import org.springframework.ide.vscode.boot.java.embadded.lang.EmbeddedLanguageSnippet;
|
||||
|
||||
public class JdtCronVisitorUtils {
|
||||
|
||||
static final String SCHEDULED_SIMPLE_NAME = "Scheduled";
|
||||
|
||||
public static EmbeddedExpression extractCron(NormalAnnotation node) {
|
||||
public static EmbeddedLanguageSnippet extractCron(NormalAnnotation node) {
|
||||
if (node.getTypeName() != null) {
|
||||
String fqn = node.getTypeName().getFullyQualifiedName();
|
||||
if (SCHEDULED_SIMPLE_NAME.equals(fqn) || Annotations.SCHEDULED.equals(fqn)) {
|
||||
@@ -36,7 +35,7 @@ public class JdtCronVisitorUtils {
|
||||
MemberValuePair pair = (MemberValuePair) value;
|
||||
String name = pair.getName().getFullyQualifiedName();
|
||||
if (name != null && "cron".equals(name) && isCronExpression(pair.getValue())) {
|
||||
return extractEmbeddedExpression(pair.getValue());
|
||||
return EmbeddedLangAstUtils.extractEmbeddedExpression(pair.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,14 +57,14 @@ public class DataQueryParameterDefinitionProvider implements IJavaDefinitionProv
|
||||
Collector<SemanticTokenData> collector = new Collector<>();
|
||||
a.accept(semanticTokensProvider.getTokensComputer(project, doc, cu, collector));
|
||||
for (SemanticTokenData t : collector.get()) {
|
||||
if ("parameter".equals(t.type()) && t.start() <= offset && offset <= t.end()) {
|
||||
if ("parameter".equals(t.type()) && t.range().getOffset() <= offset && offset <= t.range().getEnd()) {
|
||||
try {
|
||||
String parameterDescriptor = doc.get(t.start(), t.end() - t.start());
|
||||
String parameterDescriptor = doc.get(t.range().getOffset(), t.range().getLength());
|
||||
SimpleName paramName = JdtQueryDocHighlightsProvider.findParameter(m, parameterDescriptor);
|
||||
if (paramName != null) {
|
||||
LocationLink link = new LocationLink();
|
||||
link.setTargetUri(docId.getUri());
|
||||
link.setOriginSelectionRange(doc.toRange(t.start(), t.end() - t.start()));
|
||||
link.setOriginSelectionRange(doc.toRange(t.range().getOffset(), t.range().getLength()));
|
||||
link.setTargetSelectionRange(doc.toRange(paramName.getStartPosition(), paramName.getLength()));
|
||||
link.setTargetRange(link.getTargetSelectionRange());
|
||||
return List.of(link);
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.antlr.v4.runtime.atn.ATNConfigSet;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.antlr.v4.runtime.tree.ErrorNode;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
import org.springframework.ide.vscode.boot.java.embadded.lang.AntlrUtils;
|
||||
import org.springframework.ide.vscode.boot.java.spel.SpelSemanticTokens;
|
||||
import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokenData;
|
||||
import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokensDataProvider;
|
||||
@@ -75,7 +76,7 @@ public class HqlSemanticTokens implements SemanticTokensDataProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SemanticTokenData> computeTokens(String text, int initialOffset) {
|
||||
public List<SemanticTokenData> computeTokens(String text) {
|
||||
HqlLexer lexer = new HqlLexer(CharStreams.fromString(text));
|
||||
CommonTokenStream antlrTokens = new CommonTokenStream(lexer);
|
||||
HqlParser parser = new HqlParser(antlrTokens);
|
||||
@@ -109,7 +110,7 @@ public class HqlSemanticTokens implements SemanticTokensDataProvider {
|
||||
case HqlParser.WS:
|
||||
break;
|
||||
case HqlParser.SPEL:
|
||||
tokens.addAll(JpqlSemanticTokens.computeTokensFromSpelNode(node, initialOffset, optSpelTokens));
|
||||
tokens.addAll(JpqlSemanticTokens.computeTokensFromSpelNode(node, 0, optSpelTokens));
|
||||
break;
|
||||
default:
|
||||
if (HqlParser.WS < type && type <= HqlParser.YEAR) {
|
||||
@@ -132,7 +133,7 @@ public class HqlSemanticTokens implements SemanticTokensDataProvider {
|
||||
|
||||
@Override
|
||||
public void exitInstantiationTarget(InstantiationTargetContext ctx) {
|
||||
int offset = initialOffset + ctx.getStart().getStartIndex();
|
||||
int offset = ctx.getStart().getStartIndex();
|
||||
int length = ctx.getText().length();
|
||||
tokens.add(new SemanticTokenData(offset, offset + length , "method", new String[0]));
|
||||
AntlrUtils.getAllLeafs(ctx).forEach(semantics::remove);
|
||||
@@ -189,8 +190,8 @@ public class HqlSemanticTokens implements SemanticTokensDataProvider {
|
||||
parser.ql_statement();
|
||||
|
||||
semantics.entrySet().stream()
|
||||
.map(e -> new SemanticTokenData(e.getKey().getStartIndex() + initialOffset,
|
||||
e.getKey().getStartIndex() + e.getKey().getText().length() + initialOffset, e.getValue(),
|
||||
.map(e -> new SemanticTokenData(e.getKey().getStartIndex(),
|
||||
e.getKey().getStartIndex() + e.getKey().getText().length(), e.getValue(),
|
||||
new String[0]))
|
||||
.forEach(tokens::add);
|
||||
|
||||
|
||||
@@ -75,12 +75,12 @@ public class JdtDataQueriesInlayHintsProvider implements JdtInlayHintsProvider {
|
||||
}
|
||||
|
||||
private void processQuery(IJavaProject project, TextDocument doc, Collector<InlayHint> collector, MethodDeclaration m, EmbeddedQueryExpression q) {
|
||||
List<SemanticTokenData> semanticTokens = semanticTokensProvider.computeSemanticTokens(project, q.query().text(), q.query().offset(), q.isNative());
|
||||
List<SemanticTokenData> semanticTokens = semanticTokensProvider.computeSemanticTokens(project, q.query(), q.isNative());
|
||||
SemanticTokenData previousToken = null;
|
||||
for (SemanticTokenData t : semanticTokens) {
|
||||
if (isValidParameterOrdinalInputParameterToken(doc, t, previousToken)) {
|
||||
try {
|
||||
int number = Integer.parseInt(doc.get(t.start(), t.end() - t.start()));
|
||||
int number = Integer.parseInt(doc.get(t.range().getOffset(), t.range().getLength()));
|
||||
if (number > 0 && number <= m.parameters().size()) {
|
||||
Object param = m.parameters().get(number - 1);
|
||||
if (param instanceof SingleVariableDeclaration svd) {
|
||||
@@ -90,7 +90,7 @@ public class JdtDataQueriesInlayHintsProvider implements JdtInlayHintsProvider {
|
||||
hint.setLabel(Either.forLeft(paramName));
|
||||
hint.setPaddingLeft(true);
|
||||
hint.setPaddingRight(true);
|
||||
hint.setPosition(doc.toPosition(firstNonSkippedChar(doc, t.end(), c -> '%' != c)));
|
||||
hint.setPosition(doc.toPosition(firstNonSkippedChar(doc, t.range().getEnd(), c -> '%' != c)));
|
||||
|
||||
collector.accept(hint);
|
||||
}
|
||||
@@ -111,7 +111,7 @@ public class JdtDataQueriesInlayHintsProvider implements JdtInlayHintsProvider {
|
||||
private static boolean isValidParameterOrdinalInputParameterToken(TextDocument doc, SemanticTokenData token, SemanticTokenData previous) {
|
||||
if ("parameter".equals(token.type()) && previous != null && "operator".equals(previous.type())) {
|
||||
try {
|
||||
return "?".equals(doc.get(previous.start(), previous.end() - previous.start()));
|
||||
return "?".equals(doc.get(previous.range().getOffset(), previous.range().getLength()));
|
||||
} catch (BadLocationException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.eclipse.jdt.core.dom.NormalAnnotation;
|
||||
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
|
||||
import org.springframework.ide.vscode.boot.java.JdtSemanticTokensProvider;
|
||||
import org.springframework.ide.vscode.boot.java.data.jpa.queries.JdtQueryVisitorUtils.EmbeddedQueryExpression;
|
||||
import org.springframework.ide.vscode.boot.java.embadded.lang.EmbeddedLanguageSnippet;
|
||||
import org.springframework.ide.vscode.boot.java.spel.SpelSemanticTokens;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.SpringProjectUtil;
|
||||
@@ -68,7 +69,7 @@ public class JdtDataQuerySemanticTokensProvider implements JdtSemanticTokensProv
|
||||
public boolean visit(NormalAnnotation a) {
|
||||
EmbeddedQueryExpression q = JdtQueryVisitorUtils.extractQueryExpression(a);
|
||||
if (q != null) {
|
||||
computeSemanticTokens(jp, q.query().text(), q.query().offset(), q.isNative()).forEach(tokensData::accept);
|
||||
computeSemanticTokens(jp, q.query(), q.isNative()).forEach(tokensData::accept);
|
||||
}
|
||||
return super.visit(a);
|
||||
}
|
||||
@@ -77,7 +78,7 @@ public class JdtDataQuerySemanticTokensProvider implements JdtSemanticTokensProv
|
||||
public boolean visit(SingleMemberAnnotation a) {
|
||||
EmbeddedQueryExpression q = JdtQueryVisitorUtils.extractQueryExpression(a);
|
||||
if (q != null) {
|
||||
computeSemanticTokens(jp, q.query().text(), q.query().offset(), q.isNative()).forEach(tokensData::accept);
|
||||
computeSemanticTokens(jp, q.query(), q.isNative()).forEach(tokensData::accept);
|
||||
}
|
||||
return super.visit(a);
|
||||
}
|
||||
@@ -86,17 +87,22 @@ public class JdtDataQuerySemanticTokensProvider implements JdtSemanticTokensProv
|
||||
public boolean visit(MethodInvocation node) {
|
||||
EmbeddedQueryExpression q = JdtQueryVisitorUtils.extractQueryExpression(node);
|
||||
if (q != null) {
|
||||
computeSemanticTokens(jp, q.query().text(), q.query().offset(), q.isNative()).forEach(tokensData::accept);
|
||||
computeSemanticTokens(jp, q.query(), q.isNative()).forEach(tokensData::accept);
|
||||
}
|
||||
return super.visit(node);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public List<SemanticTokenData> computeSemanticTokens(IJavaProject jp, String query, int offset, boolean isNative) {
|
||||
SemanticTokensDataProvider provider = isNative ? getSqlSemanticTokensProvider(jp) : (SpringProjectUtil.hasDependencyStartingWith(jp, "hibernate-core", null) ? hqlProvider : jpqlProvider);
|
||||
public List<SemanticTokenData> computeSemanticTokens(IJavaProject jp, EmbeddedLanguageSnippet s, boolean isNative) {
|
||||
SemanticTokensDataProvider provider = isNative ? getSqlSemanticTokensProvider(jp)
|
||||
: (SpringProjectUtil.hasDependencyStartingWith(jp, "hibernate-core", null) ? hqlProvider
|
||||
: jpqlProvider);
|
||||
if (provider != null) {
|
||||
return provider.computeTokens(query, offset);
|
||||
return provider.computeTokens(s.getText()).stream()
|
||||
.flatMap(td -> s.toJavaRanges(td.range()).stream().map(r -> new SemanticTokenData(r,
|
||||
td.type(), td.modifiers())))
|
||||
.toList();
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@@ -54,9 +54,9 @@ public class JdtQueryDocHighlightsProvider implements JdtAstDocHighlightsProvide
|
||||
Collector<SemanticTokenData> collector = new Collector<>();
|
||||
a.accept(semanticTokensProvider.getTokensComputer(project, doc, cu, collector));
|
||||
for (SemanticTokenData t : collector.get()) {
|
||||
if ("parameter".equals(t.type()) && t.start() <= offset && offset <= t.end()) {
|
||||
if ("parameter".equals(t.type()) && t.range().getStart() <= offset && offset <= t.range().getEnd()) {
|
||||
try {
|
||||
String parameterDescriptor = doc.get(t.start(), t.end() - t.start());
|
||||
String parameterDescriptor = doc.get(t.range().getOffset(), t.range().getLength());
|
||||
SimpleName paramName = findParameter(m, parameterDescriptor);
|
||||
if (paramName != null) {
|
||||
DocumentHighlight highlight = new DocumentHighlight();
|
||||
|
||||
@@ -18,24 +18,21 @@ import org.eclipse.jdt.core.dom.MemberValuePair;
|
||||
import org.eclipse.jdt.core.dom.MethodInvocation;
|
||||
import org.eclipse.jdt.core.dom.NormalAnnotation;
|
||||
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
|
||||
import org.eclipse.jdt.core.dom.StringLiteral;
|
||||
import org.eclipse.jdt.core.dom.TextBlock;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchies;
|
||||
import org.springframework.ide.vscode.boot.java.embadded.lang.EmbeddedLangAstUtils;
|
||||
import org.springframework.ide.vscode.boot.java.embadded.lang.EmbeddedLanguageSnippet;
|
||||
|
||||
public class JdtQueryVisitorUtils {
|
||||
|
||||
private static final String QUERY = "Query";
|
||||
private static final String NAMED_QUERY = "NamedQuery";
|
||||
|
||||
|
||||
public record EmbeddedExpression(Expression expression, String text, int offset) {};
|
||||
|
||||
public record EmbeddedQueryExpression(EmbeddedExpression query, boolean isNative) {};
|
||||
public record EmbeddedQueryExpression(EmbeddedLanguageSnippet query, boolean isNative) {};
|
||||
|
||||
public static EmbeddedQueryExpression extractQueryExpression(SingleMemberAnnotation a) {
|
||||
if (isQueryAnnotation(a)) {
|
||||
EmbeddedExpression expression = extractEmbeddedExpression(a.getValue());
|
||||
EmbeddedLanguageSnippet expression = EmbeddedLangAstUtils.extractEmbeddedExpression(a.getValue());
|
||||
return expression == null ? null : new EmbeddedQueryExpression(expression, false);
|
||||
}
|
||||
return null;
|
||||
@@ -83,7 +80,7 @@ public class JdtQueryVisitorUtils {
|
||||
}
|
||||
}
|
||||
if (queryExpression != null) {
|
||||
EmbeddedExpression e = extractEmbeddedExpression(queryExpression);
|
||||
EmbeddedLanguageSnippet e = EmbeddedLangAstUtils.extractEmbeddedExpression(queryExpression);
|
||||
if (e != null) {
|
||||
return new EmbeddedQueryExpression(e, isNative);
|
||||
}
|
||||
@@ -96,7 +93,7 @@ public class JdtQueryVisitorUtils {
|
||||
IMethodBinding methodBinding = m.resolveMethodBinding();
|
||||
if ("jakarta.persistence.EntityManager".equals(methodBinding.getDeclaringClass().getQualifiedName())) {
|
||||
if (methodBinding.getParameterTypes().length <= 2 && "java.lang.String".equals(methodBinding.getParameterTypes()[0].getQualifiedName())) {
|
||||
EmbeddedExpression expression = extractEmbeddedExpression(queryExpr);
|
||||
EmbeddedLanguageSnippet expression = EmbeddedLangAstUtils.extractEmbeddedExpression(queryExpr);
|
||||
return expression == null ? null : new EmbeddedQueryExpression(expression, false);
|
||||
}
|
||||
}
|
||||
@@ -104,22 +101,6 @@ public class JdtQueryVisitorUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static EmbeddedExpression extractEmbeddedExpression(Expression valueExp) {
|
||||
String text = null;
|
||||
int offset = 0;
|
||||
if (valueExp instanceof StringLiteral sl) {
|
||||
text = sl.getEscapedValue();
|
||||
text = text.substring(1, text.length() - 1);
|
||||
offset = sl.getStartPosition() + 1; // +1 to skip over opening "
|
||||
} else if (valueExp instanceof TextBlock tb) {
|
||||
text = tb.getEscapedValue();
|
||||
text = text.substring(3, text.length() - 3);
|
||||
offset = tb.getStartPosition() + 3; // +3 to skip over opening """
|
||||
}
|
||||
return text == null ? null : new EmbeddedExpression(valueExp, text, offset);
|
||||
}
|
||||
|
||||
|
||||
static boolean isQueryAnnotation(Annotation a) {
|
||||
if (Annotations.DATA_QUERY.equals(a.getTypeName().getFullyQualifiedName()) || QUERY.equals(a.getTypeName().getFullyQualifiedName())) {
|
||||
ITypeBinding type = a.resolveTypeBinding();
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
import org.springframework.ide.vscode.boot.java.spel.SpelSemanticTokens;
|
||||
import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokenData;
|
||||
import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokensDataProvider;
|
||||
import org.springframework.ide.vscode.commons.util.text.Region;
|
||||
import org.springframework.ide.vscode.parser.jpql.JpqlBaseListener;
|
||||
import org.springframework.ide.vscode.parser.jpql.JpqlLexer;
|
||||
import org.springframework.ide.vscode.parser.jpql.JpqlParser;
|
||||
@@ -77,7 +78,7 @@ public class JpqlSemanticTokens implements SemanticTokensDataProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SemanticTokenData> computeTokens(String text, int initialOffset) {
|
||||
public List<SemanticTokenData> computeTokens(String text) {
|
||||
JpqlLexer lexer = new JpqlLexer(CharStreams.fromString(text));
|
||||
CommonTokenStream antlrTokens = new CommonTokenStream(lexer);
|
||||
JpqlParser parser = new JpqlParser(antlrTokens);
|
||||
@@ -114,7 +115,7 @@ public class JpqlSemanticTokens implements SemanticTokensDataProvider {
|
||||
case JpqlParser.WS:
|
||||
break;
|
||||
case JpqlParser.SPEL:
|
||||
tokens.addAll(computeTokensFromSpelNode(node, initialOffset, optSpelTokens));
|
||||
tokens.addAll(computeTokensFromSpelNode(node, 0, optSpelTokens));
|
||||
break;
|
||||
default:
|
||||
if (JpqlParser.WS < type && type <= JpqlParser.WHERE) {
|
||||
@@ -201,8 +202,8 @@ public class JpqlSemanticTokens implements SemanticTokensDataProvider {
|
||||
parser.ql_statement();
|
||||
|
||||
semantics.entrySet().stream()
|
||||
.map(e -> new SemanticTokenData(e.getKey().getStartIndex() + initialOffset,
|
||||
e.getKey().getStartIndex() + e.getKey().getText().length() + initialOffset, e.getValue(),
|
||||
.map(e -> new SemanticTokenData(e.getKey().getStartIndex(),
|
||||
e.getKey().getStartIndex() + e.getKey().getText().length(), e.getValue(),
|
||||
new String[0]))
|
||||
.forEach(tokens::add);
|
||||
|
||||
@@ -222,10 +223,14 @@ public class JpqlSemanticTokens implements SemanticTokensDataProvider {
|
||||
spelTokens.add(new SemanticTokenData(startPosition, spelStartPosition, "operator", new String[0]));
|
||||
// SPEL contents
|
||||
optSpelTokens.ifPresentOrElse(
|
||||
spelTokenProvider -> spelTokens
|
||||
.addAll(spelTokenProvider.computeTokens(node.getText().substring(2, node.getText().length() - 1), spelStartPosition)),
|
||||
() -> spelTokens.add(new SemanticTokenData(spelStartPosition, spelEndPosition, "string", new String[0])));
|
||||
|
||||
spelTokenProvider -> spelTokens.addAll(spelTokenProvider
|
||||
.computeTokens(node.getText().substring(2, node.getText().length() - 1)).stream()
|
||||
.map(td -> new SemanticTokenData(new Region(td.range().getOffset() + spelStartPosition, td.range().getLength()),
|
||||
td.type(), td.modifiers()))
|
||||
.toList()),
|
||||
() -> spelTokens
|
||||
.add(new SemanticTokenData(spelStartPosition, spelEndPosition, "string", new String[0])));
|
||||
|
||||
// '}' operator
|
||||
spelTokens.add(new SemanticTokenData(spelEndPosition, endPosition, "operator", new String[0]));
|
||||
return spelTokens;
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.antlr.v4.runtime.atn.ATNConfigSet;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.antlr.v4.runtime.tree.ErrorNode;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
import org.springframework.ide.vscode.boot.java.embadded.lang.AntlrUtils;
|
||||
import org.springframework.ide.vscode.boot.java.spel.SpelSemanticTokens;
|
||||
import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokenData;
|
||||
import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokensDataProvider;
|
||||
@@ -72,7 +73,7 @@ public class MySqlSemanticTokens implements SemanticTokensDataProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SemanticTokenData> computeTokens(String text, int initialOffset) {
|
||||
public List<SemanticTokenData> computeTokens(String text) {
|
||||
MySqlLexer lexer = new MySqlLexer(CharStreams.fromString(text));
|
||||
CommonTokenStream antlrTokens = new CommonTokenStream(lexer);
|
||||
MySqlParser parser = new MySqlParser(antlrTokens);
|
||||
@@ -90,7 +91,7 @@ public class MySqlSemanticTokens implements SemanticTokensDataProvider {
|
||||
int type = node.getSymbol().getType();
|
||||
switch (type) {
|
||||
case MySqlParser.SPEL:
|
||||
tokens.addAll(JpqlSemanticTokens.computeTokensFromSpelNode(node, initialOffset, optSpelTokens));
|
||||
tokens.addAll(JpqlSemanticTokens.computeTokensFromSpelNode(node, 0, optSpelTokens));
|
||||
break;
|
||||
case MySqlParser.ID:
|
||||
semantics.put(node.getSymbol(), "variable");
|
||||
@@ -255,17 +256,17 @@ public class MySqlSemanticTokens implements SemanticTokensDataProvider {
|
||||
if (e.getKey().getType() == MySqlLexer.DOT_ID) {
|
||||
return Stream.of(
|
||||
// the prefix '.' is an operator
|
||||
new SemanticTokenData(startIndex + initialOffset,
|
||||
startIndex + 1 + initialOffset, "operator",
|
||||
new SemanticTokenData(startIndex,
|
||||
startIndex + 1, "operator",
|
||||
new String[0]),
|
||||
// the rest whatever it was meant to be initially
|
||||
new SemanticTokenData(startIndex + 1 + initialOffset,
|
||||
startIndex + e.getKey().getText().length() + initialOffset, e.getValue(),
|
||||
new SemanticTokenData(startIndex + 1,
|
||||
startIndex + e.getKey().getText().length(), e.getValue(),
|
||||
new String[0])
|
||||
);
|
||||
} else {
|
||||
return Stream.of(new SemanticTokenData(startIndex + initialOffset,
|
||||
startIndex + e.getKey().getText().length() + initialOffset, e.getValue(),
|
||||
return Stream.of(new SemanticTokenData(startIndex,
|
||||
startIndex + e.getKey().getText().length(), e.getValue(),
|
||||
new String[0]));
|
||||
}
|
||||
})
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFin
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
import org.springframework.ide.vscode.commons.util.text.Region;
|
||||
import org.springframework.ide.vscode.java.properties.antlr.parser.AntlrParser;
|
||||
import org.springframework.ide.vscode.java.properties.parser.ParseResults;
|
||||
import org.springframework.ide.vscode.java.properties.parser.PropertiesAst.KeyValuePair;
|
||||
@@ -45,7 +46,7 @@ public class NamedQueryPropertiesReconcileEngine implements IReconcileEngine {
|
||||
ParseResults parseResults = parser.parse(doc.get());
|
||||
for (KeyValuePair pair : parseResults.ast.getPropertyValuePairs()) {
|
||||
Value value = pair.getValue();
|
||||
reconciler.reconcile(value.decode(), value.getOffset(), problemCollector);
|
||||
reconciler.reconcile(value.decode(), r -> new Region(r.getOffset() + value.getOffset(), r.getLength()), problemCollector);
|
||||
}
|
||||
} finally {
|
||||
problemCollector.endCollecting();
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.antlr.v4.runtime.atn.ATNConfigSet;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.antlr.v4.runtime.tree.ErrorNode;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
import org.springframework.ide.vscode.boot.java.embadded.lang.AntlrUtils;
|
||||
import org.springframework.ide.vscode.boot.java.spel.SpelSemanticTokens;
|
||||
import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokenData;
|
||||
import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokensDataProvider;
|
||||
@@ -73,7 +74,7 @@ public class PostgreSqlSemanticTokens implements SemanticTokensDataProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SemanticTokenData> computeTokens(String text, int initialOffset) {
|
||||
public List<SemanticTokenData> computeTokens(String text) {
|
||||
PostgreSqlLexer lexer = new PostgreSqlLexer(CharStreams.fromString(text));
|
||||
CommonTokenStream antlrTokens = new CommonTokenStream(lexer);
|
||||
PostgreSqlParser parser = new PostgreSqlParser(antlrTokens);
|
||||
@@ -109,7 +110,7 @@ public class PostgreSqlSemanticTokens implements SemanticTokensDataProvider {
|
||||
} else if (type >= PostgreSqlLexer.LineComment && type <= PostgreSqlLexer.UnterminatedBlockComment) {
|
||||
semantics.put(token, "comment");
|
||||
} else if (type == PostgreSqlLexer.SPEL) {
|
||||
tokens.addAll(JpqlSemanticTokens.computeTokensFromSpelNode(node, initialOffset, optSpelTokens));
|
||||
tokens.addAll(JpqlSemanticTokens.computeTokensFromSpelNode(node, 0, optSpelTokens));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,8 +182,8 @@ public class PostgreSqlSemanticTokens implements SemanticTokensDataProvider {
|
||||
parser.root();
|
||||
|
||||
semantics.entrySet().stream()
|
||||
.map(e -> new SemanticTokenData(e.getKey().getStartIndex() + initialOffset,
|
||||
e.getKey().getStartIndex() + e.getKey().getText().length() + initialOffset, e.getValue(),
|
||||
.map(e -> new SemanticTokenData(e.getKey().getStartIndex(),
|
||||
e.getKey().getStartIndex() + e.getKey().getText().length(), e.getValue(),
|
||||
new String[0]))
|
||||
.forEach(tokens::add);
|
||||
|
||||
|
||||
@@ -17,13 +17,11 @@ import java.util.Optional;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.eclipse.jdt.core.dom.Expression;
|
||||
import org.eclipse.jdt.core.dom.MethodInvocation;
|
||||
import org.eclipse.jdt.core.dom.NormalAnnotation;
|
||||
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
|
||||
import org.eclipse.jdt.core.dom.StringLiteral;
|
||||
import org.eclipse.jdt.core.dom.TextBlock;
|
||||
import org.springframework.ide.vscode.boot.java.data.jpa.queries.JdtQueryVisitorUtils.EmbeddedQueryExpression;
|
||||
import org.springframework.ide.vscode.boot.java.embadded.lang.AntlrReconcilerWithSpel;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.Reconciler;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.JdtAstReconciler;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.RequiredCompleteAstException;
|
||||
@@ -63,7 +61,7 @@ public class QueryJdtAstReconciler implements JdtAstReconciler {
|
||||
EmbeddedQueryExpression q = JdtQueryVisitorUtils.extractQueryExpression(node);
|
||||
if (q != null) {
|
||||
Optional<Reconciler> reconcilerOpt = q.isNative() ? getSqlReconciler(project) : Optional.of(getQueryReconciler(project));
|
||||
reconcilerOpt.ifPresent(r -> r.reconcile(q.query().text(), q.query().offset(), problemCollector));
|
||||
reconcilerOpt.ifPresent(r -> r.reconcile(q.query().getText(), q.query()::toSingleJavaRange, problemCollector));
|
||||
}
|
||||
return super.visit(node);
|
||||
}
|
||||
@@ -72,7 +70,7 @@ public class QueryJdtAstReconciler implements JdtAstReconciler {
|
||||
public boolean visit(SingleMemberAnnotation node) {
|
||||
EmbeddedQueryExpression q = JdtQueryVisitorUtils.extractQueryExpression(node);
|
||||
if (q != null) {
|
||||
getQueryReconciler(project).reconcile(q.query().text(), q.query().offset(), problemCollector);
|
||||
getQueryReconciler(project).reconcile(q.query().getText(), q.query()::toSingleJavaRange, problemCollector);
|
||||
}
|
||||
return super.visit(node);
|
||||
}
|
||||
@@ -81,7 +79,7 @@ public class QueryJdtAstReconciler implements JdtAstReconciler {
|
||||
public boolean visit(MethodInvocation node) {
|
||||
EmbeddedQueryExpression q = JdtQueryVisitorUtils.extractQueryExpression(node);
|
||||
if (q != null) {
|
||||
getQueryReconciler(project).reconcile(q.query().text(), q.query().offset(), problemCollector);
|
||||
getQueryReconciler(project).reconcile(q.query().getText(), q.query()::toSingleJavaRange, problemCollector);
|
||||
}
|
||||
return super.visit(node);
|
||||
}
|
||||
@@ -96,23 +94,23 @@ public class QueryJdtAstReconciler implements JdtAstReconciler {
|
||||
return SpringProjectUtil.hasDependencyStartingWith(project, "hibernate-core", null) ? hqlReconciler : jpqlReconciler;
|
||||
}
|
||||
|
||||
public static void reconcileExpression(Reconciler reconciler, Expression valueExp, IProblemCollector problemCollector) {
|
||||
String query = null;
|
||||
int offset = 0;
|
||||
if (valueExp instanceof StringLiteral sl) {
|
||||
query = sl.getEscapedValue();
|
||||
query = query.substring(1, query.length() - 1);
|
||||
offset = sl.getStartPosition() + 1; // +1 to skip over opening "
|
||||
} else if (valueExp instanceof TextBlock tb) {
|
||||
query = tb.getEscapedValue();
|
||||
query = query.substring(3, query.length() - 3);
|
||||
offset = tb.getStartPosition() + 3; // +3 to skip over opening """
|
||||
}
|
||||
|
||||
if (query != null) {
|
||||
reconciler.reconcile(query, offset, problemCollector);
|
||||
}
|
||||
}
|
||||
// public static void reconcileExpression(Reconciler reconciler, Expression valueExp, IProblemCollector problemCollector) {
|
||||
// String query = null;
|
||||
// int offset = 0;
|
||||
// if (valueExp instanceof StringLiteral sl) {
|
||||
// query = sl.getEscapedValue();
|
||||
// query = query.substring(1, query.length() - 1);
|
||||
// offset = sl.getStartPosition() + 1; // +1 to skip over opening "
|
||||
// } else if (valueExp instanceof TextBlock tb) {
|
||||
// query = tb.getEscapedValue();
|
||||
// query = query.substring(3, query.length() - 3);
|
||||
// offset = tb.getStartPosition() + 3; // +3 to skip over opening """
|
||||
// }
|
||||
//
|
||||
// if (query != null) {
|
||||
// reconciler.reconcile(query, offset, problemCollector);
|
||||
// }
|
||||
// }
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IJavaProject project) {
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.Sem
|
||||
import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokensDataProvider;
|
||||
import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokensHandler;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
import org.springframework.ide.vscode.commons.util.text.Region;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
import org.springframework.ide.vscode.java.properties.antlr.parser.AntlrParser;
|
||||
import org.springframework.ide.vscode.java.properties.parser.ParseResults;
|
||||
@@ -76,7 +77,9 @@ public class QueryPropertiesSemanticTokensHandler implements SemanticTokensHandl
|
||||
for (PropertiesAst.KeyValuePair node : result.ast.getPropertyValuePairs()) {
|
||||
Value value = node.getValue();
|
||||
if (value != null) {
|
||||
data.addAll(tokensProvider.computeTokens(value.decode(), value.getOffset()));
|
||||
tokensProvider.computeTokens(value.decode()).stream()
|
||||
.map(td -> new SemanticTokenData(new Region(td.range().getOffset() + value.getOffset(), td.range().getLength()), td.type(), td.modifiers()))
|
||||
.forEach(data::add);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
|
||||
@@ -8,10 +8,11 @@
|
||||
* Contributors:
|
||||
* Broadcom, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.data.jpa.queries;
|
||||
package org.springframework.ide.vscode.boot.java.embadded.lang;
|
||||
|
||||
import java.util.BitSet;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.antlr.v4.runtime.ANTLRErrorListener;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
@@ -33,6 +34,8 @@ import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemC
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblemImpl;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.IRegion;
|
||||
import org.springframework.ide.vscode.commons.util.text.Region;
|
||||
import org.springframework.ide.vscode.commons.util.text.linetracker.DefaultLineTracker;
|
||||
|
||||
public class AntlrReconciler implements Reconciler {
|
||||
@@ -57,7 +60,7 @@ public class AntlrReconciler implements Reconciler {
|
||||
this.problemType = problemType;
|
||||
}
|
||||
|
||||
protected Parser createParser(String text, int startPosition, IProblemCollector problemCollector) throws Exception {
|
||||
protected Parser createParser(String text, Function<IRegion, IRegion> mapping, IProblemCollector problemCollector) throws Exception {
|
||||
Lexer lexer = lexerClass.getDeclaredConstructor(CharStream.class).newInstance(CharStreams.fromString(text));
|
||||
CommonTokenStream antlrTokens = new CommonTokenStream(lexer);
|
||||
Parser parser = parserClass.getDeclaredConstructor(TokenStream.class).newInstance(antlrTokens);
|
||||
@@ -93,7 +96,8 @@ public class AntlrReconciler implements Reconciler {
|
||||
log.error("", e1);
|
||||
}
|
||||
}
|
||||
problemCollector.accept(new ReconcileProblemImpl(problemType, String.format("%s: %s", prefix, msg), startPosition + offset, length));
|
||||
IRegion problemRegion = mapping.apply(new Region(offset, length));
|
||||
problemCollector.accept(new ReconcileProblemImpl(problemType, String.format("%s: %s", prefix, msg), problemRegion.getOffset(), problemRegion.getLength()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -121,9 +125,9 @@ public class AntlrReconciler implements Reconciler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reconcile(String text, int startPosition, IProblemCollector problemCollector) {
|
||||
public void reconcile(String text, Function<IRegion, IRegion> mapping, IProblemCollector problemCollector) {
|
||||
try {
|
||||
Parser parser = createParser(text, startPosition, problemCollector);
|
||||
Parser parser = createParser(text, mapping, problemCollector);
|
||||
parserClass.getDeclaredMethod(parseMethod).invoke(parser);
|
||||
} catch (Throwable t) {
|
||||
log.error("", t);
|
||||
@@ -8,9 +8,10 @@
|
||||
* Contributors:
|
||||
* Broadcom, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.data.jpa.queries;
|
||||
package org.springframework.ide.vscode.boot.java.embadded.lang;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.antlr.v4.runtime.Lexer;
|
||||
import org.antlr.v4.runtime.Parser;
|
||||
@@ -21,6 +22,8 @@ import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
import org.springframework.ide.vscode.boot.java.spel.SpelReconciler;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.util.text.IRegion;
|
||||
import org.springframework.ide.vscode.commons.util.text.Region;
|
||||
|
||||
public class AntlrReconcilerWithSpel extends AntlrReconciler {
|
||||
|
||||
@@ -35,15 +38,15 @@ public class AntlrReconcilerWithSpel extends AntlrReconciler {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Parser createParser(String text, int startPosition, IProblemCollector problemCollector) throws Exception {
|
||||
Parser parser = super.createParser(text, startPosition, problemCollector);
|
||||
protected Parser createParser(String text, Function<IRegion, IRegion> mapping, IProblemCollector problemCollector) throws Exception {
|
||||
Parser parser = super.createParser(text, mapping, problemCollector);
|
||||
|
||||
// Reconcile embedded SPEL
|
||||
spelReconciler.ifPresent(r -> parser.addParseListener(new ParseTreeListener() {
|
||||
|
||||
private void processTerminal(TerminalNode node) {
|
||||
if (node.getSymbol().getType() == spelTokenType) {
|
||||
AntlrReconcilerWithSpel.reconcileEmbeddedSpelNode(node, startPosition, r, problemCollector);
|
||||
AntlrReconcilerWithSpel.reconcileEmbeddedSpelNode(node, mapping, r, problemCollector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,10 +73,9 @@ public class AntlrReconcilerWithSpel extends AntlrReconciler {
|
||||
return parser;
|
||||
}
|
||||
|
||||
private static void reconcileEmbeddedSpelNode(TerminalNode node, int initialOffset, SpelReconciler spelReconciler, IProblemCollector problemCollector) {
|
||||
int startPosition = initialOffset + node.getSymbol().getStartIndex();
|
||||
private static void reconcileEmbeddedSpelNode(TerminalNode node, Function<IRegion, IRegion> mapping, SpelReconciler spelReconciler, IProblemCollector problemCollector) {
|
||||
String spelContent = node.getSymbol().getText().substring(2, node.getSymbol().getText().length() - 1);
|
||||
spelReconciler.reconcile(spelContent, startPosition, problemCollector);
|
||||
spelReconciler.reconcile(spelContent, r -> new Region(r.getOffset() + node.getSymbol().getStartIndex(), r.getLength())/*i -> mapping.apply(i + node.getSymbol().getStartIndex())*/, problemCollector);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
* Contributors:
|
||||
* Broadcom, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.data.jpa.queries;
|
||||
package org.springframework.ide.vscode.boot.java.embadded.lang;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2024 Broadcom, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Broadcom, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.embadded.lang;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.text.IRegion;
|
||||
import org.springframework.ide.vscode.commons.util.text.Region;
|
||||
|
||||
public class CompositeEmbeddedLanguageSnippet implements EmbeddedLanguageSnippet {
|
||||
|
||||
private TreeMap<Region, EmbeddedLanguageSnippet> snippetParts;
|
||||
private String text;
|
||||
|
||||
public CompositeEmbeddedLanguageSnippet(Collection<EmbeddedLanguageSnippet> snippets) {
|
||||
snippetParts = new TreeMap<>(new Comparator<IRegion>() {
|
||||
|
||||
@Override
|
||||
public int compare(IRegion o1, IRegion o2) {
|
||||
return o1.getOffset() - o2.getOffset();
|
||||
}
|
||||
|
||||
});
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int offset = 0;
|
||||
for (EmbeddedLanguageSnippet s : snippets) {
|
||||
String t = s.getText();
|
||||
sb.append(t);
|
||||
snippetParts.putIfAbsent(new Region(offset, t.length()), s);
|
||||
offset += t.length();
|
||||
}
|
||||
this.text = sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IRegion> toJavaRanges(IRegion range) {
|
||||
List<IRegion> javaRegions = new ArrayList<>();
|
||||
Entry<Region, EmbeddedLanguageSnippet> startEntry = snippetParts.floorEntry(new Region(range.getStart(), 0));
|
||||
Entry<Region, EmbeddedLanguageSnippet> endEntry = snippetParts.floorEntry(new Region(range.getEnd(), 0));
|
||||
|
||||
|
||||
if (startEntry.getKey().equals(endEntry.getKey())) {
|
||||
// The Range is within the same snippet piece
|
||||
javaRegions.addAll(startEntry.getValue().toJavaRanges(new Region(range.getOffset() - startEntry.getKey().getOffset(), range.getLength())));
|
||||
} else {
|
||||
// The range spans a number of snippets
|
||||
// starting snippet - part of it should be included
|
||||
int offset = range.getOffset() - startEntry.getKey().getOffset();
|
||||
int length = startEntry.getKey().getLength() - offset;
|
||||
if (length > 0) {
|
||||
javaRegions.addAll(startEntry.getValue().toJavaRanges(new Region(offset, length)));
|
||||
}
|
||||
// snippet parts entirely in the request range - entire snippet range is included
|
||||
for (Entry<Region, EmbeddedLanguageSnippet> e : snippetParts.subMap(startEntry.getKey(), false, endEntry.getKey(), false).entrySet()) {
|
||||
javaRegions.addAll(e.getValue().toJavaRanges(new Region(0, e.getKey().getLength())));
|
||||
}
|
||||
// ending snippet - part of it should be included
|
||||
offset = 0;
|
||||
length = range.getEnd() - endEntry.getKey().getOffset();
|
||||
if (length > 0) {
|
||||
javaRegions.addAll(endEntry.getValue().toJavaRanges(new Region(offset, length)));
|
||||
}
|
||||
|
||||
}
|
||||
return javaRegions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toJavaOffset(int offset) {
|
||||
Entry<Region, EmbeddedLanguageSnippet> entry = snippetParts.floorEntry(new Region(offset, 0));
|
||||
return entry.getValue().toJavaOffset(offset - entry.getKey().getOffset());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2024 Broadcom, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Broadcom, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.embadded.lang;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.core.dom.Expression;
|
||||
import org.eclipse.jdt.core.dom.InfixExpression;
|
||||
import org.eclipse.jdt.core.dom.StringLiteral;
|
||||
import org.eclipse.jdt.core.dom.TextBlock;
|
||||
|
||||
public class EmbeddedLangAstUtils {
|
||||
|
||||
public static EmbeddedLanguageSnippet extractEmbeddedExpression(Expression valueExp) {
|
||||
if (valueExp instanceof StringLiteral sl) {
|
||||
return new StringLiteralLanguageSnippet(sl);
|
||||
} else if (valueExp instanceof TextBlock tb) {
|
||||
return new TextBlockLanguageSnippet(tb);
|
||||
} else if (valueExp instanceof InfixExpression ie && ie.getOperator() == InfixExpression.Operator.PLUS) {
|
||||
EmbeddedLanguageSnippet leftSnippet = extractEmbeddedExpression(ie.getLeftOperand());
|
||||
List<EmbeddedLanguageSnippet> snippets = new ArrayList<>(2 + ie.extendedOperands().size());
|
||||
if (leftSnippet == null) {
|
||||
return null;
|
||||
} else {
|
||||
snippets.add(leftSnippet);
|
||||
}
|
||||
EmbeddedLanguageSnippet rightSnippet = extractEmbeddedExpression(ie.getRightOperand());
|
||||
if (rightSnippet == null) {
|
||||
return null;
|
||||
} else {
|
||||
snippets.add(rightSnippet);
|
||||
}
|
||||
for (Object o : ie.extendedOperands()) {
|
||||
if (o instanceof Expression exp) {
|
||||
EmbeddedLanguageSnippet s = extractEmbeddedExpression(exp);
|
||||
if (s == null) {
|
||||
return null;
|
||||
} else {
|
||||
snippets.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new CompositeEmbeddedLanguageSnippet(snippets);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2024 Broadcom, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Broadcom, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.embadded.lang;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.text.IRegion;
|
||||
import org.springframework.ide.vscode.commons.util.text.Region;
|
||||
|
||||
public interface EmbeddedLanguageSnippet {
|
||||
|
||||
List<IRegion> toJavaRanges(IRegion range);
|
||||
|
||||
default IRegion toSingleJavaRange(IRegion range) {
|
||||
List<IRegion> ranges = toJavaRanges(range);
|
||||
int start = ranges.get(0).getOffset();
|
||||
int end = ranges.get(ranges.size() - 1).getEnd();
|
||||
return new Region(start, end - start);
|
||||
}
|
||||
|
||||
int toJavaOffset(int offset);
|
||||
|
||||
String getText();
|
||||
|
||||
default IRegion getTotalRange() {
|
||||
return toSingleJavaRange(new Region(0, getText().length()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2024 Broadcom, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Broadcom, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.embadded.lang;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.text.IRegion;
|
||||
import org.springframework.ide.vscode.commons.util.text.Region;
|
||||
|
||||
public class EmbeddedLanguageSnippetWithPrefixAndSuffix implements EmbeddedLanguageSnippet {
|
||||
|
||||
private final EmbeddedLanguageSnippet snippet;
|
||||
private final int start;
|
||||
private final int end;
|
||||
|
||||
public EmbeddedLanguageSnippetWithPrefixAndSuffix(EmbeddedLanguageSnippet snippet, int start, int end) {
|
||||
this.snippet = snippet;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return snippet.getText().substring(start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IRegion> toJavaRanges(IRegion range) {
|
||||
return snippet.toJavaRanges(new Region(range.getOffset() + start, range.getLength()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toJavaOffset(int offset) {
|
||||
return snippet.toJavaOffset(offset + start);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2024 Broadcom, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Broadcom, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.embadded.lang;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.core.dom.StringLiteral;
|
||||
import org.springframework.ide.vscode.commons.util.text.IRegion;
|
||||
import org.springframework.ide.vscode.commons.util.text.Region;
|
||||
|
||||
public class StringLiteralLanguageSnippet implements EmbeddedLanguageSnippet {
|
||||
|
||||
final private int literalOffset;
|
||||
final private String escapedValue;
|
||||
final private String literalValue;
|
||||
|
||||
private transient int startOffset;
|
||||
/*
|
||||
* Each region represents a tuple where:
|
||||
* - offset is the position in the snippet text.
|
||||
* - length is the number of chars symbol at that location takes in the escaped snippet text
|
||||
*/
|
||||
private transient List<Region> specialRegions;
|
||||
|
||||
public StringLiteralLanguageSnippet(StringLiteral literal) {
|
||||
this(literal.getEscapedValue(), literal.getLiteralValue(), literal.getStartPosition());
|
||||
}
|
||||
|
||||
public StringLiteralLanguageSnippet(String escapedValue, String literalValue, int literalOffset) {
|
||||
this.escapedValue = escapedValue;
|
||||
this.literalValue = literalValue;
|
||||
this.literalOffset = literalOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toJavaOffset(int offset) {
|
||||
if (specialRegions == null) {
|
||||
specialRegions = createMappings();
|
||||
}
|
||||
int mappedOffset = literalOffset + startOffset + offset;
|
||||
for (Region r : specialRegions) {
|
||||
if (offset > r.getStart()) {
|
||||
// length - 1 because 1 is added implicitly from '+ offset' above. Length of char escaped or not is >= 1
|
||||
mappedOffset += (r.getLength() - 1);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return mappedOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IRegion> toJavaRanges(IRegion range) {
|
||||
int start = toJavaOffset(range.getStart());
|
||||
int end = toJavaOffset(range.getEnd());
|
||||
return List.of(new Region(start, end - start));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return literalValue;
|
||||
}
|
||||
|
||||
private List<Region> createMappings() {
|
||||
List<Region> regions = new ArrayList<>();
|
||||
if (literalValue.length() > 0) {
|
||||
int current = 1; // skip over opening "
|
||||
startOffset = current;
|
||||
boolean escaping = false;
|
||||
// <= to include the next char after the end of the literal actual value
|
||||
for (int i = 0; i <= literalValue.length();) {
|
||||
if (escaping) {
|
||||
regions.add(new Region(i, 2));
|
||||
i++;
|
||||
current++;
|
||||
escaping = false;
|
||||
} else {
|
||||
if (escapedValue.charAt(current) == '\\') {
|
||||
escaping = escapedValue.charAt(current) == '\\';
|
||||
current++;
|
||||
} else {
|
||||
i++;
|
||||
current++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return regions;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2024 Broadcom, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Broadcom, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.embadded.lang;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.core.dom.TextBlock;
|
||||
import org.springframework.ide.vscode.commons.util.text.IRegion;
|
||||
import org.springframework.ide.vscode.commons.util.text.Region;
|
||||
|
||||
public class TextBlockLanguageSnippet implements EmbeddedLanguageSnippet {
|
||||
|
||||
final private int literalOffset;
|
||||
final private String escapedValue;
|
||||
final private String literalValue;
|
||||
|
||||
private transient int startOffset;
|
||||
private transient List<Region> specialRegions;
|
||||
|
||||
public TextBlockLanguageSnippet(TextBlock block) {
|
||||
this(block.getEscapedValue(), block.getLiteralValue(), block.getStartPosition());
|
||||
}
|
||||
|
||||
public TextBlockLanguageSnippet(String escapedValue, String literalValue, int literalOffset) {
|
||||
this.escapedValue = escapedValue;
|
||||
this.literalValue = literalValue;
|
||||
this.literalOffset = literalOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IRegion> toJavaRanges(IRegion range) {
|
||||
int start = toJavaOffset(range.getStart());
|
||||
int end = toJavaOffset(range.getEnd());
|
||||
return List.of(new Region(start, end - start));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toJavaOffset(int offset) {
|
||||
if (specialRegions == null) {
|
||||
specialRegions = createMappings();
|
||||
}
|
||||
int mappedOffset = literalOffset + startOffset + offset;
|
||||
for (Region r : specialRegions) {
|
||||
if (offset > r.getStart()) {
|
||||
// length - 1 because 1 is added implicitly from '+ offset' above. Length of char escaped or not is >= 1
|
||||
mappedOffset += (r.getLength() - 1);
|
||||
}
|
||||
}
|
||||
return mappedOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return literalValue;
|
||||
}
|
||||
|
||||
private List<Region> createMappings() {
|
||||
List<Region> regions = new ArrayList<>();
|
||||
if (literalValue.length() > 0) {
|
||||
int current = 3; // skip over opening """
|
||||
for (; current < escapedValue.length() && escapedValue.charAt(current) != '\\' && escapedValue.charAt(current) != literalValue.charAt(0); current++) {
|
||||
|
||||
}
|
||||
startOffset = current;
|
||||
boolean escaping = escapedValue.charAt(current) == '\\';
|
||||
// <= to include the next char after the end of the literal actual value
|
||||
for (int i = 0; i <= literalValue.length();) {
|
||||
if (escaping) {
|
||||
regions.add(new Region(i, 2));
|
||||
i++;
|
||||
current++;
|
||||
escaping = false;
|
||||
} else {
|
||||
if (escapedValue.charAt(current) == '\\') {
|
||||
escaping = escapedValue.charAt(current) == '\\';
|
||||
current++;
|
||||
} else {
|
||||
i++;
|
||||
current++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return regions;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -38,8 +38,8 @@ import org.eclipse.lsp4j.jsonrpc.CancelChecker;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.embadded.lang.EmbeddedLanguageSnippet;
|
||||
import org.springframework.ide.vscode.boot.java.spel.AnnotationParamSpelExtractor;
|
||||
import org.springframework.ide.vscode.boot.java.spel.AnnotationParamSpelExtractor.Snippet;
|
||||
import org.springframework.ide.vscode.boot.java.spel.SpelSemanticTokens;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.SpringProjectUtil;
|
||||
@@ -47,6 +47,7 @@ import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFin
|
||||
import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokenData;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.IRegion;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
@@ -99,7 +100,7 @@ public class CopilotCodeLensProvider implements CodeLensProvider {
|
||||
public boolean visit(SingleMemberAnnotation node) {
|
||||
Arrays.stream(spelExtractors).map(e -> e.getSpelRegion(node)).filter(o -> o.isPresent())
|
||||
.map(o -> o.get()).forEach(snippet -> {
|
||||
String additionalContext = parseSpelAndFetchContext(cu, snippet.text());
|
||||
String additionalContext = parseSpelAndFetchContext(cu, snippet.getText());
|
||||
provideCodeLensForSpelExpression(cancelToken, node, document, snippet, additionalContext, resultAccumulator);
|
||||
});
|
||||
|
||||
@@ -119,7 +120,7 @@ public class CopilotCodeLensProvider implements CodeLensProvider {
|
||||
|
||||
Arrays.stream(spelExtractors).map(e -> e.getSpelRegion(node)).filter(o -> o.isPresent())
|
||||
.map(o -> o.get()).forEach(snippet -> {
|
||||
String additionalContext = parseSpelAndFetchContext(cu, snippet.text());
|
||||
String additionalContext = parseSpelAndFetchContext(cu, snippet.getText());
|
||||
provideCodeLensForSpelExpression(cancelToken, node, document, snippet, additionalContext, resultAccumulator);
|
||||
});
|
||||
|
||||
@@ -154,7 +155,7 @@ public class CopilotCodeLensProvider implements CodeLensProvider {
|
||||
}
|
||||
|
||||
protected void provideCodeLensForSpelExpression(CancelChecker cancelToken, Annotation node, TextDocument document,
|
||||
Snippet snippet, String additionalContext, List<CodeLens> resultAccumulator) {
|
||||
EmbeddedLanguageSnippet snippet, String additionalContext, List<CodeLens> resultAccumulator) {
|
||||
cancelToken.checkCanceled();
|
||||
|
||||
if (snippet != null) {
|
||||
@@ -167,12 +168,13 @@ public class CopilotCodeLensProvider implements CodeLensProvider {
|
||||
""",additionalContext) : "";
|
||||
|
||||
CodeLens codeLens = new CodeLens();
|
||||
codeLens.setRange(document.toRange(snippet.offset(), snippet.text().length()));
|
||||
IRegion totalRange = snippet.getTotalRange();
|
||||
codeLens.setRange(document.toRange(totalRange.getStart(), totalRange.getLength()));
|
||||
|
||||
Command cmd = new Command();
|
||||
cmd.setTitle(QueryType.SPEL.getTitle());
|
||||
cmd.setCommand(CMD);
|
||||
cmd.setArguments(ImmutableList.of(QueryType.SPEL.getPrompt() + snippet.text() + "\n\n" + context));
|
||||
cmd.setArguments(ImmutableList.of(QueryType.SPEL.getPrompt() + snippet.getText() + "\n\n" + context));
|
||||
codeLens.setCommand(cmd);
|
||||
|
||||
resultAccumulator.add(codeLens);
|
||||
@@ -235,7 +237,7 @@ public class CopilotCodeLensProvider implements CodeLensProvider {
|
||||
|
||||
private List<SemanticTokenData> parseSpelExpression(String spelText) {
|
||||
try {
|
||||
return spelSemanticTokens.computeTokens(spelText, 0);
|
||||
return spelSemanticTokens.computeTokens(spelText);
|
||||
} catch (Exception e) {
|
||||
logger.error("Error computing tokens: " + e.getMessage());
|
||||
return Collections.emptyList();
|
||||
@@ -244,7 +246,7 @@ public class CopilotCodeLensProvider implements CodeLensProvider {
|
||||
|
||||
private static Set<String> extractMethodNames(List<SemanticTokenData> tokens, String spelText) {
|
||||
return tokens.stream().filter(token -> "method".equals(token.type()))
|
||||
.map(token -> spelText.substring(token.start(), token.end())).collect(Collectors.toSet());
|
||||
.map(token -> spelText.substring(token.range().getStart(), token.range().getEnd())).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
private List<String> collectMethodContexts(Set<String> methodNames, CompilationUnit cu) {
|
||||
|
||||
@@ -10,13 +10,16 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.handlers;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.util.text.IRegion;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public interface Reconciler {
|
||||
|
||||
void reconcile(String value, int startPosition, IProblemCollector problemCollector);
|
||||
void reconcile(String value, Function<IRegion, IRegion> offsetMapper, IProblemCollector problemCollector);
|
||||
|
||||
}
|
||||
|
||||
@@ -10,12 +10,16 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.handlers;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.expression.ParseException;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.ide.vscode.boot.java.SpelProblemType;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblemImpl;
|
||||
import org.springframework.ide.vscode.commons.util.text.IRegion;
|
||||
import org.springframework.ide.vscode.commons.util.text.Region;
|
||||
import org.springframework.util.SystemPropertyUtils;
|
||||
|
||||
/**
|
||||
@@ -34,7 +38,7 @@ public class SpelExpressionReconciler implements Reconciler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reconcile(String spelExpression, int startPosition, IProblemCollector problemCollector) {
|
||||
public void reconcile(String spelExpression, Function<IRegion, IRegion> mapper, IProblemCollector problemCollector) {
|
||||
if (!this.spelExpressionValidationEnabled) {
|
||||
return;
|
||||
}
|
||||
@@ -47,17 +51,11 @@ public class SpelExpressionReconciler implements Reconciler {
|
||||
catch (ParseException e) {
|
||||
String message = e.getSimpleMessage();
|
||||
int position = e.getPosition();
|
||||
|
||||
createProblem(spelExpression, message, startPosition, position, problemCollector);
|
||||
IRegion r = mapper.apply(new Region(0, position));
|
||||
ReconcileProblem problem = new ReconcileProblemImpl(SpelProblemType.JAVA_SPEL_EXPRESSION_SYNTAX, message, r.getOffset(), r.getLength());
|
||||
problemCollector.accept(problem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createProblem(String spelExpression, String message, int startPosition, int position, IProblemCollector problemCollector) {
|
||||
int start = startPosition + position;
|
||||
int length = spelExpression.length() - position;
|
||||
ReconcileProblem problem = new ReconcileProblemImpl(SpelProblemType.JAVA_SPEL_EXPRESSION_SYNTAX, message, start, length);
|
||||
problemCollector.accept(problem);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,9 +17,11 @@ import org.eclipse.jdt.core.dom.Expression;
|
||||
import org.eclipse.jdt.core.dom.MemberValuePair;
|
||||
import org.eclipse.jdt.core.dom.NormalAnnotation;
|
||||
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
|
||||
import org.eclipse.jdt.core.dom.StringLiteral;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchies;
|
||||
import org.springframework.ide.vscode.boot.java.embadded.lang.EmbeddedLangAstUtils;
|
||||
import org.springframework.ide.vscode.boot.java.embadded.lang.EmbeddedLanguageSnippet;
|
||||
import org.springframework.ide.vscode.boot.java.embadded.lang.EmbeddedLanguageSnippetWithPrefixAndSuffix;
|
||||
|
||||
public final class AnnotationParamSpelExtractor {
|
||||
|
||||
@@ -87,7 +89,7 @@ public final class AnnotationParamSpelExtractor {
|
||||
this.prefixSuffixes = List.of(new PrefixSuffix(paramValuePrefix, paramValueSuffx), new PrefixSuffix("", ""));
|
||||
}
|
||||
|
||||
public Optional<Snippet> getSpelRegion(NormalAnnotation a) {
|
||||
public Optional<EmbeddedLanguageSnippet> getSpelRegion(NormalAnnotation a) {
|
||||
if (paramName == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
@@ -104,8 +106,9 @@ public final class AnnotationParamSpelExtractor {
|
||||
String name = pair.getName().getFullyQualifiedName();
|
||||
if (name != null && name.equals(paramName)) {
|
||||
Expression expression = pair.getValue();
|
||||
if (expression instanceof StringLiteral) {
|
||||
return fromStringLiteral((StringLiteral) expression);
|
||||
EmbeddedLanguageSnippet embeddedSnippet = EmbeddedLangAstUtils.extractEmbeddedExpression(expression);
|
||||
if (embeddedSnippet != null) {
|
||||
return fromEmbeddedSnippet(embeddedSnippet);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -114,7 +117,7 @@ public final class AnnotationParamSpelExtractor {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public Optional<Snippet> getSpelRegion(SingleMemberAnnotation a) {
|
||||
public Optional<EmbeddedLanguageSnippet> getSpelRegion(SingleMemberAnnotation a) {
|
||||
if (this.paramName != null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
@@ -124,26 +127,24 @@ public final class AnnotationParamSpelExtractor {
|
||||
}
|
||||
|
||||
Expression valueExp = a.getValue();
|
||||
|
||||
if (valueExp instanceof StringLiteral) {
|
||||
return fromStringLiteral((StringLiteral) valueExp);
|
||||
}
|
||||
|
||||
EmbeddedLanguageSnippet embeddedSnippet = EmbeddedLangAstUtils.extractEmbeddedExpression(valueExp);
|
||||
if (embeddedSnippet != null) {
|
||||
return fromEmbeddedSnippet(embeddedSnippet);
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private Optional<Snippet> fromStringLiteral(StringLiteral valueExp) {
|
||||
String value = valueExp.getEscapedValue();
|
||||
value = value.substring(1, value.length() - 1);
|
||||
if (value != null) {
|
||||
private Optional<EmbeddedLanguageSnippet> fromEmbeddedSnippet(EmbeddedLanguageSnippet embeddedSnippet) {
|
||||
String value = embeddedSnippet.getText();
|
||||
if (value != null && !value.isBlank()) {
|
||||
for (PrefixSuffix ps : prefixSuffixes) {
|
||||
int startIdx = value.indexOf(ps.prefix);
|
||||
if (startIdx >= 0) {
|
||||
int endIdx = value.lastIndexOf(ps.suffix);
|
||||
if (endIdx >= 0) {
|
||||
String spelText = value.substring(startIdx + ps.prefix.length(), endIdx);
|
||||
int offset = valueExp.getStartPosition() + startIdx + ps.prefix.length() + 1;
|
||||
return Optional.of(new Snippet(spelText, offset));
|
||||
return Optional.of(new EmbeddedLanguageSnippetWithPrefixAndSuffix(embeddedSnippet, startIdx + ps.prefix.length(), endIdx));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class JdtSpelReconciler implements JdtAstReconciler {
|
||||
.map(e -> e.getSpelRegion(node))
|
||||
.filter(o -> o.isPresent())
|
||||
.map(o -> o.get())
|
||||
.forEach(snippet -> spelReconciler.reconcile(snippet.text(), snippet.offset(), problemCollector));
|
||||
.forEach(snippet -> spelReconciler.reconcile(snippet.getText(), snippet::toSingleJavaRange, problemCollector));
|
||||
return super.visit(node);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public class JdtSpelReconciler implements JdtAstReconciler {
|
||||
.map(e -> e.getSpelRegion(node))
|
||||
.filter(o -> o.isPresent())
|
||||
.map(o -> o.get())
|
||||
.forEach(snippet -> spelReconciler.reconcile(snippet.text(), snippet.offset(), problemCollector));
|
||||
.forEach(snippet -> spelReconciler.reconcile(snippet.getText(), snippet::toSingleJavaRange, problemCollector));
|
||||
return super.visit(node);
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,10 @@ public class JdtSpelSemanticTokensProvider implements JdtSemanticTokensProvider
|
||||
.map(e -> e.getSpelRegion(node))
|
||||
.filter(o -> o.isPresent())
|
||||
.map(o -> o.get())
|
||||
.forEach(snippet -> tokensProvider.computeTokens(snippet.text(), snippet.offset()).forEach(collector::accept));
|
||||
.forEach(snippet -> tokensProvider.computeTokens(snippet.getText()).stream()
|
||||
.flatMap(td -> snippet.toJavaRanges(td.range()).stream().map(r -> new SemanticTokenData(r,
|
||||
td.type(), td.modifiers())))
|
||||
.forEach(collector::accept));
|
||||
return super.visit(node);
|
||||
}
|
||||
|
||||
@@ -70,7 +73,10 @@ public class JdtSpelSemanticTokensProvider implements JdtSemanticTokensProvider
|
||||
.map(e -> e.getSpelRegion(node))
|
||||
.filter(o -> o.isPresent())
|
||||
.map(o -> o.get())
|
||||
.forEach(snippet -> tokensProvider.computeTokens(snippet.text(), snippet.offset()).forEach(collector::accept));
|
||||
.forEach(snippet -> tokensProvider.computeTokens(snippet.getText()).stream()
|
||||
.flatMap(td -> snippet.toJavaRanges(td.range()).stream().map(r -> new SemanticTokenData(r,
|
||||
td.type(), td.modifiers())))
|
||||
.forEach(collector::accept));
|
||||
return super.visit(node);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ import org.antlr.v4.runtime.atn.ATNConfigSet;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.antlr.v4.runtime.tree.ErrorNode;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
import org.springframework.ide.vscode.boot.java.data.jpa.queries.AntlrUtils;
|
||||
import org.springframework.ide.vscode.boot.java.embadded.lang.AntlrUtils;
|
||||
import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokenData;
|
||||
import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokensDataProvider;
|
||||
import org.springframework.ide.vscode.parser.placeholder.PropertyPlaceHolderBaseListener;
|
||||
@@ -56,7 +56,7 @@ public class PropertyPlaceHolderSemanticTokens implements SemanticTokensDataProv
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SemanticTokenData> computeTokens(String text, int initialOffset) {
|
||||
public List<SemanticTokenData> computeTokens(String text) {
|
||||
PropertyPlaceHolderLexer lexer = new PropertyPlaceHolderLexer(CharStreams.fromString(text));
|
||||
CommonTokenStream antlrTokens = new CommonTokenStream(lexer);
|
||||
PropertyPlaceHolderParser parser = new PropertyPlaceHolderParser(antlrTokens);
|
||||
@@ -74,7 +74,7 @@ public class PropertyPlaceHolderSemanticTokens implements SemanticTokensDataProv
|
||||
public void exitKey(KeyContext ctx) {
|
||||
// Remove all children nodes semantics as they will be replaced by a single token spanning multiple AST nodes
|
||||
AntlrUtils.getAllLeafs(ctx).forEach(semantics::remove);
|
||||
int start = ctx.getStart().getStartIndex() + initialOffset;
|
||||
int start = ctx.getStart().getStartIndex();
|
||||
int end = start + ctx.getText().length();
|
||||
tokens.add(new SemanticTokenData(start, end, "property", new String[0]));
|
||||
}
|
||||
@@ -87,7 +87,7 @@ public class PropertyPlaceHolderSemanticTokens implements SemanticTokensDataProv
|
||||
}
|
||||
if (ctx.value() != null) {
|
||||
ValueContext valueCtx = ctx.value();
|
||||
int start = valueCtx.getStart().getStartIndex() + initialOffset;
|
||||
int start = valueCtx.getStart().getStartIndex();
|
||||
int end = start + valueCtx.getText().length();
|
||||
tokens.add(new SemanticTokenData(start, end, "string", new String[0]));
|
||||
}
|
||||
@@ -148,8 +148,8 @@ public class PropertyPlaceHolderSemanticTokens implements SemanticTokensDataProv
|
||||
parser.start();
|
||||
|
||||
tokens.addAll(semantics.entrySet().stream()
|
||||
.map(e -> new SemanticTokenData(e.getKey().getStartIndex() + initialOffset,
|
||||
e.getKey().getStartIndex() + e.getKey().getText().length() + initialOffset, e.getValue(),
|
||||
.map(e -> new SemanticTokenData(e.getKey().getStartIndex(),
|
||||
e.getKey().getStartIndex() + e.getKey().getText().length(), e.getValue(),
|
||||
new String[0]))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
|
||||
@@ -52,15 +52,17 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.ide.vscode.boot.index.SpringMetamodelIndex;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.IJavaDefinitionProvider;
|
||||
import org.springframework.ide.vscode.boot.java.embadded.lang.EmbeddedLanguageSnippet;
|
||||
import org.springframework.ide.vscode.boot.java.links.SourceLinks;
|
||||
import org.springframework.ide.vscode.boot.java.spel.AnnotationParamSpelExtractor.Snippet;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
|
||||
import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.DocumentRegion;
|
||||
import org.springframework.ide.vscode.commons.util.text.IRegion;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
import org.springframework.ide.vscode.commons.util.text.Region;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
import org.springframework.ide.vscode.parser.spel.SpelLexer;
|
||||
import org.springframework.ide.vscode.parser.spel.SpelParser;
|
||||
@@ -116,11 +118,11 @@ public class SpelDefinitionProvider implements IJavaDefinitionProvider {
|
||||
return e.getSpelRegion((SingleMemberAnnotation) a);
|
||||
else if (a instanceof NormalAnnotation)
|
||||
return e.getSpelRegion((NormalAnnotation) a);
|
||||
return Optional.<Snippet>empty();
|
||||
return Optional.<EmbeddedLanguageSnippet>empty();
|
||||
}).filter(o -> o.isPresent()).map(o -> o.get())
|
||||
.filter(snippet -> {
|
||||
int tokenEndIndex = snippet.offset() + snippet.text().length();
|
||||
return snippet.offset() <= (offset) && (offset) <= tokenEndIndex;
|
||||
IRegion snippetRegion = snippet.getTotalRange();
|
||||
return snippetRegion.getStart() <= (offset) && (offset) <= snippetRegion.getEnd();
|
||||
}).forEach(snippet -> {
|
||||
List<TokenData> beanReferenceTokens = computeTokens(snippet, offset);
|
||||
if (beanReferenceTokens != null && beanReferenceTokens.size() > 0) {
|
||||
@@ -213,8 +215,8 @@ public class SpelDefinitionProvider implements IJavaDefinitionProvider {
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<TokenData> computeTokens(Snippet snippet, int offset) {
|
||||
SpelLexer lexer = new SpelLexer(CharStreams.fromString(snippet.text()));
|
||||
private List<TokenData> computeTokens(EmbeddedLanguageSnippet snippet, int offset) {
|
||||
SpelLexer lexer = new SpelLexer(CharStreams.fromString(snippet.getText()));
|
||||
CommonTokenStream antlrTokens = new CommonTokenStream(lexer);
|
||||
SpelParser parser = new SpelParser(antlrTokens);
|
||||
|
||||
@@ -236,8 +238,9 @@ public class SpelDefinitionProvider implements IJavaDefinitionProvider {
|
||||
}
|
||||
|
||||
private void addTokenData(Token sym, int offset) {
|
||||
int start = sym.getStartIndex() + snippet.offset();
|
||||
int end = sym.getStartIndex() + sym.getText().length() + snippet.offset();
|
||||
List<IRegion> symbolRegions = snippet.toJavaRanges(new Region(sym.getStartIndex(), sym.getText().length()));
|
||||
int start = symbolRegions.get(0).getStart();
|
||||
int end = symbolRegions.get(symbolRegions.size() - 1).getEnd();
|
||||
if (isOffsetWithinToken(start, end, offset)) {
|
||||
beanReferenceTokens.add(new TokenData(sym.getText(), start, end));
|
||||
}
|
||||
@@ -254,10 +257,10 @@ public class SpelDefinitionProvider implements IJavaDefinitionProvider {
|
||||
return beanReferenceTokens;
|
||||
}
|
||||
|
||||
private Optional<Tuple2<String, String>> parseAndExtractMethodClassPairFromSpel(Snippet snippet, int offset) {
|
||||
private Optional<Tuple2<String, String>> parseAndExtractMethodClassPairFromSpel(EmbeddedLanguageSnippet snippet, int offset) {
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
try {
|
||||
org.springframework.expression.Expression expression = parser.parseExpression(snippet.text());
|
||||
org.springframework.expression.Expression expression = parser.parseExpression(snippet.getText());
|
||||
|
||||
SpelExpression spelExpressionAST = (SpelExpression) expression;
|
||||
SpelNode rootNode = spelExpressionAST.getAST();
|
||||
@@ -269,8 +272,8 @@ public class SpelDefinitionProvider implements IJavaDefinitionProvider {
|
||||
}
|
||||
|
||||
private Optional<Tuple2<String, String>> extractMethodClassPairFromSpelNodes(SpelNode node, SpelNode parent,
|
||||
Snippet snippet, int offset) {
|
||||
if (node instanceof MethodReference && checkOffsetInMethodName(node, snippet.offset(), offset)) {
|
||||
EmbeddedLanguageSnippet snippet, int offset) {
|
||||
if (node instanceof MethodReference && checkOffsetInMethodName(node, snippet.toJavaOffset(0), offset)) {
|
||||
MethodReference methodRef = (MethodReference) node;
|
||||
String methodName = methodRef.getName();
|
||||
String className = extractClassNameFromParent(parent);
|
||||
|
||||
@@ -10,14 +10,18 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.spel;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.antlr.v4.runtime.Parser;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ErrorNode;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeListener;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
import org.springframework.ide.vscode.boot.java.SpelProblemType;
|
||||
import org.springframework.ide.vscode.boot.java.data.jpa.queries.AntlrReconciler;
|
||||
import org.springframework.ide.vscode.boot.java.embadded.lang.AntlrReconciler;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.util.text.IRegion;
|
||||
import org.springframework.ide.vscode.commons.util.text.Region;
|
||||
import org.springframework.ide.vscode.parser.placeholder.PropertyPlaceHolderLexer;
|
||||
import org.springframework.ide.vscode.parser.placeholder.PropertyPlaceHolderParser;
|
||||
import org.springframework.ide.vscode.parser.spel.SpelLexer;
|
||||
@@ -40,25 +44,27 @@ public class SpelReconciler extends AntlrReconciler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reconcile(String text, int startPosition, IProblemCollector problemCollector) {
|
||||
public void reconcile(String text, Function<IRegion, IRegion> mapper, IProblemCollector problemCollector) {
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
super.reconcile(text, startPosition, problemCollector);
|
||||
super.reconcile(text, mapper, problemCollector);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Parser createParser(String text, int startPosition, IProblemCollector problemCollector) throws Exception {
|
||||
Parser parser = super.createParser(text, startPosition, problemCollector);
|
||||
protected Parser createParser(String text, Function<IRegion, IRegion> mapper, IProblemCollector problemCollector) throws Exception {
|
||||
Parser parser = super.createParser(text, mapper, problemCollector);
|
||||
|
||||
// Reconcile embedded SPEL
|
||||
parser.addParseListener(new ParseTreeListener() {
|
||||
|
||||
private void processTerminal(TerminalNode node) {
|
||||
if (node.getSymbol().getType() == SpelLexer.PROPERTY_PLACE_HOLDER) {
|
||||
int placeHolderStartPosition = startPosition + node.getSymbol().getStartIndex() + 2;
|
||||
String content = node.getSymbol().getText().substring(2, node.getSymbol().getText().length() - 1);
|
||||
propertyHolderReconciler.reconcile(content, placeHolderStartPosition, problemCollector);
|
||||
propertyHolderReconciler.reconcile(content, r -> {
|
||||
IRegion n = mapper.apply(r);
|
||||
return new Region(n.getOffset() + node.getSymbol().getStartIndex() + 2, n.getLength());
|
||||
}, problemCollector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,66 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.spel;
|
||||
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.*;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.AND;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.ASSIGN;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.BACKTICK;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.BEAN_REF;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.COLON;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.COMMA;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.DEC;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.DIV;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.DOT;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.DOUBLE_QUOTED_STRING;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.ELVIS;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.EQ;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.EQ_KEYWORD;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.FACTORY_BEAN_REF;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.FALSE;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.GE;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.GE_KEYWORD;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.GT;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.GT_KEYWORD;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.HASH;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.IDENTIFIER;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.INC;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.INTEGER_LITERAL;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.LCURLY;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.LE;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.LE_KEYWORD;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.LPAREN;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.LSQUARE;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.LT;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.LT_KEYWORD;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.MATCHES;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.MINUS;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.MOD;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.NE;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.NEW;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.NE_KEYWORD;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.NOT;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.NULL;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.OR;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.PLUS;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.POWER;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.PROJECT;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.PROPERTY_PLACE_HOLDER;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.QMARK;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.RCURLY;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.REAL_LITERAL;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.RPAREN;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.RSQUARE;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.SAFE_NAVI;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.SELECT;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.SELECT_FIRST;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.SELECT_LAST;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.SEMICOLON;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.SINGLE_QUOTED_STRING;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.STAR;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.STRING_LITERAL;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.SYMBOLIC_AND;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.SYMBOLIC_OR;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.T;
|
||||
import static org.springframework.ide.vscode.parser.spel.SpelLexer.TRUE;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
@@ -38,6 +97,7 @@ import org.antlr.v4.runtime.tree.ErrorNode;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokenData;
|
||||
import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokensDataProvider;
|
||||
import org.springframework.ide.vscode.commons.util.text.Region;
|
||||
import org.springframework.ide.vscode.parser.spel.SpelLexer;
|
||||
import org.springframework.ide.vscode.parser.spel.SpelParser;
|
||||
import org.springframework.ide.vscode.parser.spel.SpelParser.BeanReferenceContext;
|
||||
@@ -71,7 +131,7 @@ public class SpelSemanticTokens implements SemanticTokensDataProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SemanticTokenData> computeTokens(String text, int initialOffset) {
|
||||
public List<SemanticTokenData> computeTokens(String text) {
|
||||
SpelLexer lexer = new SpelLexer(CharStreams.fromString(text));
|
||||
CommonTokenStream antlrTokens = new CommonTokenStream(lexer);
|
||||
SpelParser parser = new SpelParser(antlrTokens);
|
||||
@@ -158,7 +218,7 @@ public class SpelSemanticTokens implements SemanticTokensDataProvider {
|
||||
semantics.put(node.getSymbol(), "string");
|
||||
break;
|
||||
case PROPERTY_PLACE_HOLDER:
|
||||
tokens.addAll(computeTokensFromPropertyPlaceHolderNode(node, initialOffset));
|
||||
tokens.addAll(computeTokensFromPropertyPlaceHolderNode(node));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -215,7 +275,7 @@ public class SpelSemanticTokens implements SemanticTokensDataProvider {
|
||||
semantics.remove(ctx.INTEGER_LITERAL().getSymbol());
|
||||
semantics.remove(ctx.RSQUARE().getSymbol());
|
||||
|
||||
int start = ctx.getStart().getStartIndex() + initialOffset;
|
||||
int start = ctx.getStart().getStartIndex();
|
||||
int end = start + ctx.getText().length();
|
||||
tokens.add(new SemanticTokenData(start, end, "parameter", new String[0]));
|
||||
}
|
||||
@@ -260,8 +320,8 @@ public class SpelSemanticTokens implements SemanticTokensDataProvider {
|
||||
parser.spelExpr();
|
||||
|
||||
tokens.addAll(semantics.entrySet().stream()
|
||||
.map(e -> new SemanticTokenData(e.getKey().getStartIndex() + initialOffset,
|
||||
e.getKey().getStartIndex() + e.getKey().getText().length() + initialOffset, e.getValue(),
|
||||
.map(e -> new SemanticTokenData(e.getKey().getStartIndex(),
|
||||
e.getKey().getStartIndex() + e.getKey().getText().length(), e.getValue(),
|
||||
new String[0]))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
@@ -270,18 +330,19 @@ public class SpelSemanticTokens implements SemanticTokensDataProvider {
|
||||
return tokens;
|
||||
}
|
||||
|
||||
private Collection<? extends SemanticTokenData> computeTokensFromPropertyPlaceHolderNode(TerminalNode node,
|
||||
int initialOffset) {
|
||||
private Collection<? extends SemanticTokenData> computeTokensFromPropertyPlaceHolderNode(TerminalNode node) {
|
||||
List<SemanticTokenData> placeHolderTokens = new ArrayList<>();
|
||||
|
||||
int startPosition = initialOffset + node.getSymbol().getStartIndex();
|
||||
int startPosition = node.getSymbol().getStartIndex();
|
||||
int placeHolderStartPosition = startPosition + 2;
|
||||
int endPosition = startPosition + node.getText().length();
|
||||
int placeHolderEndPosition = endPosition - 1;
|
||||
// '${' operator
|
||||
placeHolderTokens.add(new SemanticTokenData(startPosition, placeHolderStartPosition, "operator", new String[0]));
|
||||
// Property Place Holder contents
|
||||
placeHolderTokens.addAll(propertyPlaceHolderSemanticTokens.computeTokens(node.getText().substring(2, node.getText().length() - 1), placeHolderStartPosition));
|
||||
propertyPlaceHolderSemanticTokens.computeTokens(node.getText().substring(2, node.getText().length() - 1))
|
||||
.stream().map(td -> new SemanticTokenData(new Region(td.range().getOffset() + placeHolderStartPosition, td.range().getLength()), td.type(), td.modifiers()))
|
||||
.forEach(placeHolderTokens::add);
|
||||
// '}' operator
|
||||
placeHolderTokens.add(new SemanticTokenData(placeHolderEndPosition, endPosition, "operator", new String[0]));
|
||||
return placeHolderTokens;
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.eclipse.lemminx.dom.DOMNode;
|
||||
import org.eclipse.lemminx.dom.DOMRange;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.Reconciler;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.util.text.Region;
|
||||
|
||||
/**
|
||||
* @author mlippert
|
||||
@@ -68,7 +69,7 @@ public class XMLElementReconciler {
|
||||
|
||||
if (value != null && value.startsWith(prefix) && value.endsWith(postfix)) {
|
||||
String valueToReconcile = value.substring(prefix.length(), value.length() - postfix.length());
|
||||
reconciler.reconcile(valueToReconcile, start + prefix.length() + 1, problemCollector);
|
||||
reconciler.reconcile(valueToReconcile, r -> new Region(r.getOffset() + start + prefix.length() + 1, r.getLength()), problemCollector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -26,27 +27,27 @@ public class CronReconcilerTest {
|
||||
|
||||
@Test
|
||||
void noProblems_1() {
|
||||
reconciler.reconcile("0 0 0 L-3 * *", 0, collector);
|
||||
reconciler.reconcile("0 0 0 L-3 * *", Function.identity(), collector);
|
||||
assertEquals(0, problems.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void DayOfTheWeekProblems_1() {
|
||||
reconciler.reconcile("0 0 0 8 * MAR-JUL", 0, collector);
|
||||
reconciler.reconcile("0 0 0 8 * MAR-JUL", Function.identity(), collector);
|
||||
assertEquals(1, problems.size());
|
||||
assertReconcileProblem(problems.get(0), CronProblemType.FIELD, 10, 6);
|
||||
}
|
||||
|
||||
@Test
|
||||
void noProblems_3() {
|
||||
reconciler.reconcile("MAR-JUL 0 0 8 * *", 0, collector);
|
||||
reconciler.reconcile("MAR-JUL 0 0 8 * *", Function.identity(), collector);
|
||||
assertEquals(1, problems.size());
|
||||
assertReconcileProblem(problems.get(0), CronProblemType.FIELD, 0, 7);
|
||||
}
|
||||
|
||||
@Test
|
||||
void syntax_and_field_problems_1() {
|
||||
reconciler.reconcile("0 0 0 8LW * MARCH-JUL", 0, collector);
|
||||
reconciler.reconcile("0 0 0 8LW * MARCH-JUL", Function.identity(), collector);
|
||||
assertEquals(3, problems.size());
|
||||
assertReconcileProblem(problems.get(0), CronProblemType.SYNTAX, 7, 2);
|
||||
assertReconcileProblem(problems.get(1), CronProblemType.SYNTAX, 12, 5);
|
||||
@@ -55,14 +56,14 @@ public class CronReconcilerTest {
|
||||
|
||||
@Test
|
||||
void syntax_problems_2() {
|
||||
reconciler.reconcile("qq#3 0 Blah 1-88LW * JUL-MARCH", 0, collector);
|
||||
reconciler.reconcile("qq#3 0 Blah 1-88LW * JUL-MARCH", Function.identity(), collector);
|
||||
assertEquals(1, problems.size());
|
||||
assertReconcileProblem(problems.get(0), CronProblemType.SYNTAX, 0, 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void syntax_problems_3() {
|
||||
reconciler.reconcile("10/2. * * ? * MON-5", 0, collector);
|
||||
reconciler.reconcile("10/2. * * ? * MON-5", Function.identity(), collector);
|
||||
assertEquals(1, problems.size());
|
||||
assertReconcileProblem(problems.get(0), CronProblemType.SYNTAX, 4, 0);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class CronSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void topHoueEveryDayEveryWeek() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 * * * *", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 * * * *");
|
||||
assertThat(tokens.size()).isEqualTo(6);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 1, "number", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(2, 3, "number", new String[0]));
|
||||
@@ -43,7 +43,7 @@ public class CronSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void everyTenSeconds() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("*/10 * * * * *", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("*/10 * * * * *");
|
||||
assertThat(tokens.size()).isEqualTo(8);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 1, "operator", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(1, 2, "operator", new String[0]));
|
||||
@@ -57,7 +57,7 @@ public class CronSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void betweenEightAndTenEveryDay() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 8-10 * * *", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 8-10 * * *");
|
||||
assertThat(tokens.size()).isEqualTo(8);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 1, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(2, 3, "number", new String[0])); // 0
|
||||
@@ -71,7 +71,7 @@ public class CronSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void everyDayBetweenSixAndSeven() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 6,19 * * *", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 6,19 * * *");
|
||||
assertThat(tokens.size()).isEqualTo(8);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 1, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(2, 3, "number", new String[0])); // 0
|
||||
@@ -85,7 +85,7 @@ public class CronSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void everyHalfHourBetweenEightAndEleven() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0/30 8-10 * * *", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0/30 8-10 * * *");
|
||||
assertThat(tokens.size()).isEqualTo(10);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 1, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(2, 3, "number", new String[0])); // 0
|
||||
@@ -101,7 +101,7 @@ public class CronSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void nineToFiveOnWeekdays() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 9-17 * * MON-FRI", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 9-17 * * MON-FRI");
|
||||
assertThat(tokens.size()).isEqualTo(10);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 1, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(2, 3, "number", new String[0])); // 0
|
||||
@@ -117,7 +117,7 @@ public class CronSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void christmas() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 25 12 ?", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 25 12 ?");
|
||||
assertThat(tokens.size()).isEqualTo(6);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 1, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(2, 3, "number", new String[0])); // 0
|
||||
@@ -129,7 +129,7 @@ public class CronSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void lastDayOfMonthAtMidnight() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 L * *", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 L * *");
|
||||
assertThat(tokens.size()).isEqualTo(6);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 1, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(2, 3, "number", new String[0])); // 0
|
||||
@@ -141,7 +141,7 @@ public class CronSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void thirdToLasttDayOfMonthAtMidnight() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 L-3 * *", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 L-3 * *");
|
||||
assertThat(tokens.size()).isEqualTo(8);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 1, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(2, 3, "number", new String[0])); // 0
|
||||
@@ -155,7 +155,7 @@ public class CronSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void firstWeekDayOfMonthAtMidnight() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 1W * *", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 1W * *");
|
||||
assertThat(tokens.size()).isEqualTo(7);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 1, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(2, 3, "number", new String[0])); // 0
|
||||
@@ -168,7 +168,7 @@ public class CronSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void lastWeekDayOfMonthAtMidnight() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 LW * *", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 LW * *");
|
||||
assertThat(tokens.size()).isEqualTo(6);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 1, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(2, 3, "number", new String[0])); // 0
|
||||
@@ -180,7 +180,7 @@ public class CronSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void lastFridayOfMonthAtMidnight() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 * * 5L", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 * * 5L");
|
||||
assertThat(tokens.size()).isEqualTo(7);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 1, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(2, 3, "number", new String[0])); // 0
|
||||
@@ -193,7 +193,7 @@ public class CronSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void lastThursdayOfMonthAtMidnight() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 * * THUL", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 * * THUL");
|
||||
assertThat(tokens.size()).isEqualTo(7);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 1, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(2, 3, "number", new String[0])); // 0
|
||||
@@ -206,7 +206,7 @@ public class CronSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void secondFridayOfMonthAtMidnight() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 ? * 5#2", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 ? * 5#2");
|
||||
assertThat(tokens.size()).isEqualTo(8);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 1, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(2, 3, "number", new String[0])); // 0
|
||||
@@ -220,7 +220,7 @@ public class CronSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void firstMondayOfMonthAtMidnight() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 ? * MON#1", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 ? * MON#1");
|
||||
assertThat(tokens.size()).isEqualTo(8);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 1, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(2, 3, "number", new String[0])); // 0
|
||||
@@ -234,7 +234,7 @@ public class CronSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void macro() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("@yearly", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("@yearly");
|
||||
assertThat(tokens.size()).isEqualTo(1);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 7, "macro", new String[0])); // @yearly
|
||||
}
|
||||
@@ -242,7 +242,7 @@ public class CronSemanticTokensTest {
|
||||
@Test
|
||||
void errors_1() {
|
||||
provider = new CronSemanticTokens();
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 8LW * Foo#bar", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 8LW * Foo#bar");
|
||||
assertThat(tokens.size()).isEqualTo(9);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 1, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(2, 3, "number", new String[0])); // 0
|
||||
@@ -258,7 +258,7 @@ public class CronSemanticTokensTest {
|
||||
@Test
|
||||
void errors_2() {
|
||||
provider = new CronSemanticTokens();
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("qq#3 0 Blah 1-88LW * JUL-MARCH", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("qq#3 0 Blah 1-88LW * JUL-MARCH");
|
||||
assertThat(tokens.size()).isEqualTo(13);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 2, "enum", new String[0])); // qq
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(2, 3, "operator", new String[0])); // #
|
||||
|
||||
@@ -83,35 +83,35 @@ public class JdtCronSemanticTokensProviderTest {
|
||||
|
||||
SemanticTokenData token = tokens.get(0);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(117, 118, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("0");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("0");
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(119, 120, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("0");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("0");
|
||||
|
||||
token = tokens.get(2);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(121, 122, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("0");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("0");
|
||||
|
||||
token = tokens.get(3);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(123, 124, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("?");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("?");
|
||||
|
||||
token = tokens.get(4);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(125, 126, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("*");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("*");
|
||||
|
||||
token = tokens.get(5);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(127, 128, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("5");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("5");
|
||||
|
||||
token = tokens.get(6);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(128, 129, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("#");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("#");
|
||||
|
||||
token = tokens.get(7);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(129, 130, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("2");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("2");
|
||||
|
||||
}
|
||||
|
||||
@@ -142,31 +142,31 @@ public class JdtCronSemanticTokensProviderTest {
|
||||
|
||||
SemanticTokenData token = tokens.get(0);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(117, 118, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("0");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("0");
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(119, 120, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("0");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("0");
|
||||
|
||||
token = tokens.get(2);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(121, 122, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("0");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("0");
|
||||
|
||||
token = tokens.get(3);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(123, 124, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("*");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("*");
|
||||
|
||||
token = tokens.get(4);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(125, 126, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("*");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("*");
|
||||
|
||||
token = tokens.get(5);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(127, 130, "enum", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("THU");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("THU");
|
||||
|
||||
token = tokens.get(6);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(130, 131, "method", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("L");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("L");
|
||||
|
||||
}
|
||||
|
||||
@@ -197,35 +197,35 @@ public class JdtCronSemanticTokensProviderTest {
|
||||
|
||||
SemanticTokenData token = tokens.get(0);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(117, 118, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("0");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("0");
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(119, 120, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("0");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("0");
|
||||
|
||||
token = tokens.get(2);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(121, 122, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("0");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("0");
|
||||
|
||||
token = tokens.get(3);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(123, 124, "method", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("L");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("L");
|
||||
|
||||
token = tokens.get(4);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(124, 125, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("-");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("-");
|
||||
|
||||
token = tokens.get(5);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(125, 126, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("3");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("3");
|
||||
|
||||
token = tokens.get(6);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(127, 128, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("*");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("*");
|
||||
|
||||
token = tokens.get(7);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(129, 130, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("*");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("*");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -255,39 +255,39 @@ public class JdtCronSemanticTokensProviderTest {
|
||||
|
||||
SemanticTokenData token = tokens.get(0);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(117, 118, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("0");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("0");
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(119, 120, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("0");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("0");
|
||||
|
||||
token = tokens.get(2);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(121, 122, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("0");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("0");
|
||||
|
||||
token = tokens.get(3);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(123, 124, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("8");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("8");
|
||||
|
||||
token = tokens.get(4);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(124, 126, "method", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("LW");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("LW");
|
||||
|
||||
token = tokens.get(5);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(127, 128, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("*");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("*");
|
||||
|
||||
token = tokens.get(6);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(129, 132, "enum", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("Foo");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("Foo");
|
||||
|
||||
token = tokens.get(7);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(132, 133, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("#");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("#");
|
||||
|
||||
token = tokens.get(8);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(133, 136, "enum", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("bar");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -317,55 +317,55 @@ public class JdtCronSemanticTokensProviderTest {
|
||||
|
||||
SemanticTokenData token = tokens.get(0);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(117, 119, "enum", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("qq");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("qq");
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(119, 120, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("#");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("#");
|
||||
|
||||
token = tokens.get(2);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(120, 121, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("3");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("3");
|
||||
|
||||
token = tokens.get(3);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(122, 123, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("0");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("0");
|
||||
|
||||
token = tokens.get(4);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(124, 128, "enum", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("Blah");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("Blah");
|
||||
|
||||
token = tokens.get(5);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(129, 130, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("1");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("1");
|
||||
|
||||
token = tokens.get(6);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(130, 131, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("-");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("-");
|
||||
|
||||
token = tokens.get(7);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(131, 133, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("88");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("88");
|
||||
|
||||
token = tokens.get(8);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(133, 135, "method", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("LW");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("LW");
|
||||
|
||||
token = tokens.get(9);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(136, 137, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("*");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("*");
|
||||
|
||||
token = tokens.get(10);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(138, 141, "enum", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("JUL");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("JUL");
|
||||
|
||||
token = tokens.get(11);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(141, 142, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("-");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("-");
|
||||
|
||||
token = tokens.get(12);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(142, 147, "enum", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("MARCH");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("MARCH");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -32,7 +32,7 @@ public class HqlSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void simpleQuery_1() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT owner FROM Owner owner", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT owner FROM Owner owner");
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(7, 12, "variable", new String[0]));
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(13, 17, "keyword", new String[0]));
|
||||
@@ -42,21 +42,9 @@ public class HqlSemanticTokensTest {
|
||||
assertThat(tokens.size()).isEqualTo(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
void initialOffset() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT owner FROM Owner owner", 3);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(3, 9, "keyword", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(10, 15, "variable", new String[0]));
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(16, 20, "keyword", new String[0]));
|
||||
assertThat(tokens.get(3)).isEqualTo(new SemanticTokenData(21, 26, "class", new String[0]));
|
||||
assertThat(tokens.get(4)).isEqualTo(new SemanticTokenData(27, 32, "variable", new String[0]));
|
||||
|
||||
assertThat(tokens.size()).isEqualTo(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
void query_with_conflicting_groupby() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT g FROM Group g GROUP BY g.name", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT g FROM Group g GROUP BY g.name");
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(7, 8, "variable", new String[0]));
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(9, 13, "keyword", new String[0]));
|
||||
@@ -73,7 +61,7 @@ public class HqlSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void query_with_parameter() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT DISTINCT owner FROM Owner owner left join owner.pets WHERE owner.lastName LIKE :lastName%", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT DISTINCT owner FROM Owner owner left join owner.pets WHERE owner.lastName LIKE :lastName%");
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0])); // SELECT
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(7, 15, "keyword", new String[0])); // DISTINCT
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(16, 21, "variable", new String[0])); // owner
|
||||
@@ -99,7 +87,7 @@ public class HqlSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void query_with_SPEL() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:#{id}", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:#{id}");
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0])); // SELECT
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(7, 12, "variable", new String[0])); // owner
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(13, 17, "keyword", new String[0])); // FROM
|
||||
@@ -127,7 +115,7 @@ public class HqlSemanticTokensTest {
|
||||
@Test
|
||||
void query_with_SPEL_Tokens() {
|
||||
provider = new HqlSemanticTokens(Optional.of(new SpelSemanticTokens()));
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:#{id}", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:#{id}");
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0])); // SELECT
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(7, 12, "variable", new String[0])); // owner
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(13, 17, "keyword", new String[0])); // FROM
|
||||
@@ -155,7 +143,7 @@ public class HqlSemanticTokensTest {
|
||||
@Test
|
||||
void query_with_complex_SPEL_Tokens() {
|
||||
provider = new HqlSemanticTokens(Optional.of(new SpelSemanticTokens()));
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:#{someBean.someProperty != null ? someBean.someProperty : 'default'}", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:#{someBean.someProperty != null ? someBean.someProperty : 'default'}");
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0])); // SELECT
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(7, 12, "variable", new String[0])); // owner
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(13, 17, "keyword", new String[0])); // FROM
|
||||
@@ -193,7 +181,7 @@ public class HqlSemanticTokensTest {
|
||||
@Test
|
||||
void instatiotation_1() {
|
||||
provider = new HqlSemanticTokens(Optional.of(new SpelSemanticTokens()));
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT new com.example.ls.issue.SampleTableSizePojo(t.schemaName, sum(t.tableSize) ) FROM MTables t GROUP BY t.schemaName ORDER BY sum(t.tableSize) DESC", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT new com.example.ls.issue.SampleTableSizePojo(t.schemaName, sum(t.tableSize) ) FROM MTables t GROUP BY t.schemaName ORDER BY sum(t.tableSize) DESC");
|
||||
assertThat(tokens.size()).isEqualTo(32);
|
||||
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0])); // SELECT
|
||||
|
||||
@@ -78,27 +78,27 @@ public class JdtDataQuerySemanticTokensProviderTest {
|
||||
|
||||
SemanticTokenData token = tokens.get(0);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(120, 126, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("SELECT");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("SELECT");
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(127, 135, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("DISTINCT");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("DISTINCT");
|
||||
|
||||
token = tokens.get(2);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(136, 141, "variable", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("owner");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("owner");
|
||||
|
||||
token = tokens.get(3);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(142, 146, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("FROM");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("FROM");
|
||||
|
||||
token = tokens.get(4);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(147, 152, "class", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("Owner");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("Owner");
|
||||
|
||||
token = tokens.get(5);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(153, 158, "variable", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("owner");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("owner");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -126,27 +126,27 @@ public class JdtDataQuerySemanticTokensProviderTest {
|
||||
|
||||
SemanticTokenData token = tokens.get(0);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(125, 131, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("SELECT");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("SELECT");
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(132, 140, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("DISTINCT");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("DISTINCT");
|
||||
|
||||
token = tokens.get(2);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(141, 146, "variable", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("owner");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("owner");
|
||||
|
||||
token = tokens.get(3);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(147, 151, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("FROM");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("FROM");
|
||||
|
||||
token = tokens.get(4);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(152, 157, "class", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("Owner");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("Owner");
|
||||
|
||||
token = tokens.get(5);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(158, 163, "variable", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("owner");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("owner");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -172,27 +172,27 @@ public class JdtDataQuerySemanticTokensProviderTest {
|
||||
|
||||
SemanticTokenData token = tokens.get(0);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(128, 134, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("SELECT");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("SELECT");
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(135, 143, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("DISTINCT");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("DISTINCT");
|
||||
|
||||
token = tokens.get(2);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(144, 149, "variable", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("owner");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("owner");
|
||||
|
||||
token = tokens.get(3);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(150, 154, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("FROM");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("FROM");
|
||||
|
||||
token = tokens.get(4);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(155, 160, "class", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("Owner");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("Owner");
|
||||
|
||||
token = tokens.get(5);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(161, 166, "variable", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("owner");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("owner");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -219,27 +219,27 @@ public class JdtDataQuerySemanticTokensProviderTest {
|
||||
|
||||
SemanticTokenData token = tokens.get(0);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(176, 182, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("SELECT");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("SELECT");
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(183, 191, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("DISTINCT");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("DISTINCT");
|
||||
|
||||
token = tokens.get(2);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(192, 197, "variable", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("owner");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("owner");
|
||||
|
||||
token = tokens.get(3);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(198, 202, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("FROM");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("FROM");
|
||||
|
||||
token = tokens.get(4);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(203, 208, "class", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("Owner");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("Owner");
|
||||
|
||||
token = tokens.get(5);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(209, 214, "variable", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("owner");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("owner");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -268,27 +268,27 @@ public class JdtDataQuerySemanticTokensProviderTest {
|
||||
|
||||
SemanticTokenData token = tokens.get(0);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(181, 187, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("SELECT");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("SELECT");
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(188, 196, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("DISTINCT");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("DISTINCT");
|
||||
|
||||
token = tokens.get(2);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(197, 202, "variable", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("owner");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("owner");
|
||||
|
||||
token = tokens.get(3);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(203, 207, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("FROM");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("FROM");
|
||||
|
||||
token = tokens.get(4);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(208, 213, "class", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("Owner");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("Owner");
|
||||
|
||||
token = tokens.get(5);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(214, 219, "variable", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("owner");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("owner");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -313,47 +313,47 @@ public class JdtDataQuerySemanticTokensProviderTest {
|
||||
List<SemanticTokenData> tokens = computeTokens(cu);
|
||||
|
||||
SemanticTokenData token = tokens.get(0);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("SELECT");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("SELECT");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(128, 134, "keyword", new String[0]));
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("*");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("*");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(135, 136, "operator", new String[0]));
|
||||
|
||||
token = tokens.get(2);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("FROM");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("FROM");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(137, 141, "keyword", new String[0]));
|
||||
|
||||
token = tokens.get(3);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("USERS");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("USERS");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(142, 147, "variable", new String[0]));
|
||||
|
||||
token = tokens.get(4);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("u");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("u");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(148, 149, "variable", new String[0]));
|
||||
|
||||
token = tokens.get(5);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("WHERE");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("WHERE");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(150, 155, "keyword", new String[0]));
|
||||
|
||||
token = tokens.get(6);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("u");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("u");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(156, 157, "variable", new String[0]));
|
||||
|
||||
token = tokens.get(7);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo(".");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo(".");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(157, 158, "operator", new String[0]));
|
||||
|
||||
token = tokens.get(8);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("status");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("status");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(158, 164, "property", new String[0]));
|
||||
|
||||
token = tokens.get(9);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("=");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("=");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(165, 166, "operator", new String[0]));
|
||||
|
||||
token = tokens.get(10);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("1");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("1");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(167, 168, "number", new String[0]));
|
||||
|
||||
}
|
||||
@@ -380,59 +380,59 @@ public class JdtDataQuerySemanticTokensProviderTest {
|
||||
List<SemanticTokenData> tokens = computeTokens(cu);
|
||||
|
||||
SemanticTokenData token = tokens.get(0);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("SELECT");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("SELECT");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(128, 134, "keyword", new String[0]));
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("*");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("*");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(135, 136, "operator", new String[0]));
|
||||
|
||||
token = tokens.get(2);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("FROM");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("FROM");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(137, 141, "keyword", new String[0]));
|
||||
|
||||
token = tokens.get(3);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("USERS");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("USERS");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(142, 147, "variable", new String[0]));
|
||||
|
||||
token = tokens.get(4);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("u");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("u");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(148, 149, "variable", new String[0]));
|
||||
|
||||
token = tokens.get(5);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("WHERE");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("WHERE");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(150, 155, "keyword", new String[0]));
|
||||
|
||||
token = tokens.get(6);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("u");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("u");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(156, 157, "variable", new String[0]));
|
||||
|
||||
token = tokens.get(7);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo(".");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo(".");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(157, 158, "operator", new String[0]));
|
||||
|
||||
token = tokens.get(8);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("status");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("status");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(158, 164, "property", new String[0]));
|
||||
|
||||
token = tokens.get(9);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("=");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("=");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(165, 166, "operator", new String[0]));
|
||||
|
||||
token = tokens.get(10);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("?");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("?");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(167, 168, "operator", new String[0]));
|
||||
|
||||
token = tokens.get(11);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("#{");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("#{");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(168, 170, "operator", new String[0]));
|
||||
|
||||
token = tokens.get(12);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("status");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("status");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(170, 176, "variable", new String[0]));
|
||||
|
||||
token = tokens.get(13);
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("}");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("}");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(176, 177, "operator", new String[0]));
|
||||
}
|
||||
|
||||
@@ -457,27 +457,84 @@ public class JdtDataQuerySemanticTokensProviderTest {
|
||||
|
||||
SemanticTokenData token = tokens.get(0);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(101, 107, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("SELECT");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("SELECT");
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(108, 116, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("DISTINCT");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("DISTINCT");
|
||||
|
||||
token = tokens.get(2);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(117, 122, "variable", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("owner");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("owner");
|
||||
|
||||
token = tokens.get(3);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(123, 127, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("FROM");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("FROM");
|
||||
|
||||
token = tokens.get(4);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(128, 133, "class", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("Owner");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("Owner");
|
||||
|
||||
token = tokens.get(5);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(134, 139, "variable", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("owner");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("owner");
|
||||
}
|
||||
|
||||
@Test
|
||||
void nativeConcatenatedStringQuery() throws Exception {
|
||||
String source = """
|
||||
package my.package
|
||||
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
|
||||
public interface OwnerRepository {
|
||||
|
||||
@Query(value = "SELECT" +
|
||||
" DIS" +
|
||||
"TINCT" +
|
||||
" test FROM Te" +
|
||||
"st", nativeQuery = true)
|
||||
void findByLastName();
|
||||
}
|
||||
""";
|
||||
|
||||
String uri = Paths.get(jp.getLocationUri()).resolve("src/main/resource/my/package/OwnerRepository.java").toUri()
|
||||
.toASCIIString();
|
||||
CompilationUnit cu = CompilationUnitCache.parse2(source.toCharArray(), uri, "OwnerRepository.java", jp);
|
||||
|
||||
assertThat(cu).isNotNull();
|
||||
|
||||
List<SemanticTokenData> tokens = computeTokens(cu);
|
||||
|
||||
SemanticTokenData token = tokens.get(0);
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("SELECT");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(128, 134, "keyword", new String[0]));
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("DIS");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(142, 145, "keyword", new String[0]));
|
||||
|
||||
token = tokens.get(2);
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("TINCT");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(152, 157, "keyword", new String[0]));
|
||||
|
||||
token = tokens.get(3);
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("test");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(165, 169, "variable", new String[0]));
|
||||
|
||||
token = tokens.get(4);
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("FROM");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(170, 174, "keyword", new String[0]));
|
||||
|
||||
token = tokens.get(5);
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("Te");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(175, 177, "variable", new String[0]));
|
||||
|
||||
token = tokens.get(6);
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("st");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(184, 186, "variable", new String[0]));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public class JpqlSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void simpleQuery_1() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT owner FROM Owner owner", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT owner FROM Owner owner");
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(7, 12, "variable", new String[0]));
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(13, 17, "keyword", new String[0]));
|
||||
@@ -42,21 +42,9 @@ public class JpqlSemanticTokensTest {
|
||||
assertThat(tokens.size()).isEqualTo(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
void initialOffset() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT owner FROM Owner owner", 3);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(3, 9, "keyword", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(10, 15, "variable", new String[0]));
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(16, 20, "keyword", new String[0]));
|
||||
assertThat(tokens.get(3)).isEqualTo(new SemanticTokenData(21, 26, "class", new String[0]));
|
||||
assertThat(tokens.get(4)).isEqualTo(new SemanticTokenData(27, 32, "variable", new String[0]));
|
||||
|
||||
assertThat(tokens.size()).isEqualTo(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
void query_with_conflicting_groupby() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT g FROM G g GROUP BY g.name", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT g FROM G g GROUP BY g.name");
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0])); // SELECT
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(7, 8, "variable", new String[0])); // g
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(9, 13, "keyword", new String[0])); // FROM
|
||||
@@ -73,7 +61,7 @@ public class JpqlSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void query_with_parameter() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT f from Student f LEFT JOIN f.classTbls s WHERE s.ClassName = :className", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT f from Student f LEFT JOIN f.classTbls s WHERE s.ClassName = :className");
|
||||
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0])); // SELECT
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(7, 8, "variable", new String[0])); // f
|
||||
@@ -99,7 +87,7 @@ public class JpqlSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void query_with_SPEL() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:#{id}", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:#{id}");
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0])); // SELECT
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(7, 12, "variable", new String[0])); // owner
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(13, 17, "keyword", new String[0])); // FROM
|
||||
@@ -127,7 +115,7 @@ public class JpqlSemanticTokensTest {
|
||||
@Test
|
||||
void query_with_SPEL_Tokens() {
|
||||
provider = new JpqlSemanticTokens(Optional.of(new SpelSemanticTokens()));
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:#{id}", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:#{id}");
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0])); // SELECT
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(7, 12, "variable", new String[0])); // owner
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(13, 17, "keyword", new String[0])); // FROM
|
||||
|
||||
@@ -32,7 +32,7 @@ public class MySqlSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void simple() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT * from Document document WHERE document.id=fn_module_candidates()", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT * from Document document WHERE document.id=fn_module_candidates()");
|
||||
assertThat(tokens.size()).isEqualTo(13);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(7, 8, "operator", new String[0]));
|
||||
@@ -52,7 +52,7 @@ public class MySqlSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void parametersInQuery() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("DELETE FROM component_document WHERE item_document_id = :itemDocumentId", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("DELETE FROM component_document WHERE item_document_id = :itemDocumentId");
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(7, 11, "keyword", new String[0]));
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(12, 30, "variable", new String[0]));
|
||||
@@ -67,7 +67,7 @@ public class MySqlSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void spelInQuery() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("DELETE FROM component_document WHERE item_document_id = :#{someBean}", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("DELETE FROM component_document WHERE item_document_id = :#{someBean}");
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(7, 11, "keyword", new String[0]));
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(12, 30, "variable", new String[0]));
|
||||
@@ -84,7 +84,7 @@ public class MySqlSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void complexSpelInQuery() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("DELETE FROM component_document WHERE item_document_id = :#{someBean.someProperty != null ? someBean.someProperty : 'default'}", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("DELETE FROM component_document WHERE item_document_id = :#{someBean.someProperty != null ? someBean.someProperty : 'default'}");
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(7, 11, "keyword", new String[0]));
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(12, 30, "variable", new String[0]));
|
||||
|
||||
@@ -32,7 +32,7 @@ public class PostgreSqlSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void simple() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT * from fn_module_candidates", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT * from fn_module_candidates");
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(7, 8, "operator", new String[0]));
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(9, 13, "keyword", new String[0]));
|
||||
@@ -51,7 +51,7 @@ public class PostgreSqlSemanticTokensTest {
|
||||
WHERE document.project_id=?1
|
||||
AND json_path_exists(document.content::jsonb, ('strict $.content.**.id ? (@ == "\\' || representation.targetobjectid || \\'")')::jsonpath)
|
||||
)
|
||||
""", 0);
|
||||
""");
|
||||
assertThat(tokens.size()).isEqualTo(43);
|
||||
|
||||
assertThat(tokens.get(10)).isEqualTo(new SemanticTokenData(74, 75, "parameter", new String[0])); // 1 from ?1
|
||||
@@ -66,7 +66,7 @@ public class PostgreSqlSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void spelInQuery() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("DELETE FROM component_document WHERE item_document_id = :#{someBean}", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("DELETE FROM component_document WHERE item_document_id = :#{someBean}");
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(7, 11, "keyword", new String[0]));
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(12, 30, "variable", new String[0]));
|
||||
@@ -83,7 +83,7 @@ public class PostgreSqlSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void semiColonAtEnd() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens(" select count(*) from anecdote where anecdote_id=:anecdote ; ", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens(" select count(*) from anecdote where anecdote_id=:anecdote ; ");
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(1, 7, "keyword", new String[0])); // select
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(8, 13, "method", new String[0])); // count
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(13, 14, "operator", new String[0])); // (
|
||||
@@ -103,7 +103,7 @@ public class PostgreSqlSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void parameterInLimitClause_1() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT * FROM cards ORDER BY random() LIMIT ?2", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT * FROM cards ORDER BY random() LIMIT ?2");
|
||||
assertThat(tokens.size()).isEqualTo(12);
|
||||
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0]));
|
||||
@@ -122,7 +122,7 @@ public class PostgreSqlSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void parameterInLimitClause_2() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT * FROM cards ORDER BY random() LIMIT ?2", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT * FROM cards ORDER BY random() LIMIT ?2");
|
||||
assertThat(tokens.size()).isEqualTo(12);
|
||||
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0]));
|
||||
@@ -141,7 +141,7 @@ public class PostgreSqlSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void parameterInLimitClause_3() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT * FROM cards ORDER BY random() LIMIT :#{qq}", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT * FROM cards ORDER BY random() LIMIT :#{qq}");
|
||||
assertThat(tokens.size()).isEqualTo(14);
|
||||
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0]));
|
||||
@@ -162,7 +162,7 @@ public class PostgreSqlSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void parameterInLimitClause_4() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT * FROM cards ORDER BY random() LIMIT :limit", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT * FROM cards ORDER BY random() LIMIT :limit");
|
||||
assertThat(tokens.size()).isEqualTo(12);
|
||||
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0]));
|
||||
@@ -181,19 +181,19 @@ public class PostgreSqlSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void notInInsideWhereClausePredicate() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("delete from SAMPLE_TABLE where id not in (select top 1 id from SAMPLE_TABLE order by TABLE_NAME desc)", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("delete from SAMPLE_TABLE where id not in (select top 1 id from SAMPLE_TABLE order by TABLE_NAME desc)");
|
||||
assertThat(tokens.size()).isEqualTo(19);
|
||||
}
|
||||
|
||||
@Test
|
||||
void keywordAsIdentifier() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT SCHEMA_NAME, TABLE_NAME, VERSION from SAMPLE_TABLE", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT SCHEMA_NAME, TABLE_NAME, VERSION from SAMPLE_TABLE");
|
||||
assertThat(tokens.size()).isEqualTo(8);
|
||||
}
|
||||
|
||||
@Test
|
||||
void topInSelectClause() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("select top 1 * from SAMPLE_TABLE where SCHEMA_NAME = ?1", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("select top 1 * from SAMPLE_TABLE where SCHEMA_NAME = ?1");
|
||||
assertThat(tokens.size()).isEqualTo(11);
|
||||
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0]));
|
||||
@@ -212,7 +212,7 @@ public class PostgreSqlSemanticTokensTest {
|
||||
@Test
|
||||
void over_clause_1() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary;\n"
|
||||
+ "", 0);
|
||||
+ "");
|
||||
assertThat(tokens.size()).isEqualTo(20);
|
||||
}
|
||||
|
||||
@@ -222,21 +222,21 @@ public class PostgreSqlSemanticTokensTest {
|
||||
SELECT depname, empno, salary,
|
||||
rank() OVER (PARTITION BY depname ORDER BY salary DESC)
|
||||
FROM empsalary;
|
||||
""", 0);
|
||||
""");
|
||||
assertThat(tokens.size()).isEqualTo(23);
|
||||
}
|
||||
|
||||
@Test
|
||||
void over_clause_3() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT salary, sum(salary) OVER () FROM empsalary;"
|
||||
+ "", 0);
|
||||
+ "");
|
||||
assertThat(tokens.size()).isEqualTo(13);
|
||||
}
|
||||
|
||||
@Test
|
||||
void over_clause_4() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT salary, sum(salary) OVER (ORDER BY salary) FROM empsalary;"
|
||||
+ "", 0);
|
||||
+ "");
|
||||
assertThat(tokens.size()).isEqualTo(16);
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ public class PostgreSqlSemanticTokensTest {
|
||||
FROM empsalary
|
||||
) AS ss
|
||||
WHERE pos < 3;
|
||||
""", 0);
|
||||
""");
|
||||
assertThat(tokens.size()).isEqualTo(46);
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ public class PostgreSqlSemanticTokensTest {
|
||||
SELECT sum(salary) OVER w, avg(salary) OVER w
|
||||
FROM empsalary
|
||||
WINDOW w AS (PARTITION BY depname ORDER BY salary DESC);
|
||||
""", 0);
|
||||
""");
|
||||
assertThat(tokens.size()).isEqualTo(29);
|
||||
}
|
||||
|
||||
@@ -282,7 +282,7 @@ public class PostgreSqlSemanticTokensTest {
|
||||
(rn = 1 OR status = 10)
|
||||
AND (scenario = 11 OR scenario = 8)
|
||||
ORDER BY status DESC
|
||||
""", 0);
|
||||
""");
|
||||
assertThat(tokens.size()).isEqualTo(74);
|
||||
}
|
||||
|
||||
@@ -290,7 +290,7 @@ public class PostgreSqlSemanticTokensTest {
|
||||
void collate_1() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("""
|
||||
SELECT DISTINCT test COLLATE "numeric" FROM Test
|
||||
""", 0);
|
||||
""");
|
||||
assertThat(tokens.size()).isEqualTo(7);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0])); // SELECT
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(7, 15, "keyword", new String[0])); // DISTICT
|
||||
@@ -303,9 +303,24 @@ public class PostgreSqlSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void collate_2() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("""
|
||||
SELECT DISTINCT test COLLATE \"numeric\" FROM Test
|
||||
""");
|
||||
assertThat(tokens.size()).isEqualTo(7);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0])); // SELECT
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(7, 15, "keyword", new String[0])); // DISTICT
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(16, 20, "variable", new String[0])); // test
|
||||
assertThat(tokens.get(3)).isEqualTo(new SemanticTokenData(21, 28, "keyword", new String[0])); // COLLATE
|
||||
assertThat(tokens.get(4)).isEqualTo(new SemanticTokenData(29, 38, "variable", new String[0])); // \"numeric\"
|
||||
assertThat(tokens.get(5)).isEqualTo(new SemanticTokenData(39, 43, "keyword", new String[0])); // FROM
|
||||
assertThat(tokens.get(6)).isEqualTo(new SemanticTokenData(44, 48, "variable", new String[0])); // Test
|
||||
}
|
||||
|
||||
@Test
|
||||
void collate_3() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("""
|
||||
SELECT a COLLATE "de_DE" < b FROM test1
|
||||
""", 0);
|
||||
""");
|
||||
assertThat(tokens.size()).isEqualTo(8);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "keyword", new String[0])); // SELECT
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(7, 8, "variable", new String[0])); // a
|
||||
|
||||
@@ -81,39 +81,39 @@ public class JdtSpelSemanticTokensProviderTest {
|
||||
|
||||
SemanticTokenData token = tokens.get(0);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(119, 122, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("new");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("new");
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(123, 129, "method", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("String");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("String");
|
||||
|
||||
token = tokens.get(2);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(129, 130, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("(");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("(");
|
||||
|
||||
token = tokens.get(3);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(130, 143, "string", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("'hello world'");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("'hello world'");
|
||||
|
||||
token = tokens.get(4);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(143, 144, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo(")");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo(")");
|
||||
|
||||
token = tokens.get(5);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(144, 145, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo(".");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo(".");
|
||||
|
||||
token = tokens.get(6);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(145, 156, "method", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("toUpperCase");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("toUpperCase");
|
||||
|
||||
token = tokens.get(7);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(156, 157, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("(");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("(");
|
||||
|
||||
token = tokens.get(8);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(157, 158, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo(")");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo(")");
|
||||
|
||||
}
|
||||
|
||||
@@ -142,16 +142,16 @@ public class JdtSpelSemanticTokensProviderTest {
|
||||
assertThat(tokens.size()).isEqualTo(3);
|
||||
|
||||
SemanticTokenData token = tokens.get(0);
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("'invalid alphabetic string #$1'");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(113, 144, "string", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("'invalid alphabetic string #$1'");
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(145, 152, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("matches");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("matches");
|
||||
|
||||
token = tokens.get(2);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(153, 166, "string", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("'[a-zA-Z\\s]+'");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("'[a-zA-Z\\s]+'");
|
||||
|
||||
}
|
||||
|
||||
@@ -182,15 +182,108 @@ public class JdtSpelSemanticTokensProviderTest {
|
||||
|
||||
SemanticTokenData token = tokens.get(0);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(121, 125, "variable", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("demo");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("demo");
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(125, 126, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo(".");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo(".");
|
||||
|
||||
token = tokens.get(2);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(126, 130, "property", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("cron");
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("cron");
|
||||
}
|
||||
|
||||
@Test
|
||||
void concatenatedString() throws Exception {
|
||||
String source = """
|
||||
package my.package
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
public class Owner {
|
||||
|
||||
@Value("#{'inval" + "id alphabetic s" + "tring #$1' mat" + "ches '[a-z" + "A-Z\\s]+' }")
|
||||
String s;
|
||||
|
||||
}
|
||||
""";
|
||||
|
||||
String uri = Paths.get(jp.getLocationUri()).resolve("src/main/resource/my/package/OwnerRepository.java").toUri().toASCIIString();
|
||||
CompilationUnit cu = CompilationUnitCache.parse2(source.toCharArray(), uri, "OwnerRepository.java", jp);
|
||||
|
||||
assertThat(cu).isNotNull();
|
||||
|
||||
List<SemanticTokenData> tokens = computeTokens(cu);
|
||||
|
||||
assertThat(tokens.size()).isEqualTo(7);
|
||||
//id alphabetic string #$1'
|
||||
SemanticTokenData token = tokens.get(0);
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("'inval");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(113, 119, "string", new String[0]));
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("id alphabetic s");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(124, 139, "string", new String[0]));
|
||||
|
||||
token = tokens.get(2);
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("tring #$1'");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(144, 154, "string", new String[0]));
|
||||
|
||||
token = tokens.get(3);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(155, 158, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("mat");
|
||||
|
||||
token = tokens.get(4);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(163, 167, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("ches");
|
||||
|
||||
token = tokens.get(5);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(168, 173, "string", new String[0]));
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("'[a-z");
|
||||
|
||||
token = tokens.get(6);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(178, 186, "string", new String[0]));
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("A-Z\\s]+'");
|
||||
}
|
||||
|
||||
@Test
|
||||
void textBlock() throws Exception {
|
||||
String source = """
|
||||
package my.package
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
public class Owner {
|
||||
|
||||
@Value(\"""
|
||||
#{'invalid alphabetic string #$1' matches '[a-zA-Z\\s]+' }
|
||||
\""")
|
||||
String s;
|
||||
|
||||
}
|
||||
""";
|
||||
|
||||
String uri = Paths.get(jp.getLocationUri()).resolve("src/main/resource/my/package/OwnerRepository.java").toUri().toASCIIString();
|
||||
CompilationUnit cu = CompilationUnitCache.parse2(source.toCharArray(), uri, "OwnerRepository.java", jp);
|
||||
|
||||
assertThat(cu).isNotNull();
|
||||
|
||||
List<SemanticTokenData> tokens = computeTokens(cu);
|
||||
|
||||
assertThat(tokens.size()).isEqualTo(3);
|
||||
|
||||
SemanticTokenData token = tokens.get(0);
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("'invalid alphabetic string #$1'");
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(118, 149, "string", new String[0]));
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(150, 157, "keyword", new String[0]));
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("matches");
|
||||
|
||||
token = tokens.get(2);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(158, 171, "string", new String[0]));
|
||||
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("'[a-zA-Z\\s]+'");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ public class PropertyPlaceHolderSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void propertyWithDefault() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("server.port:5673", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("server.port:5673");
|
||||
assertThat(tokens.size()).isEqualTo(3);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 11, "property", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(11, 12, "operator", new String[0]));
|
||||
@@ -24,14 +24,14 @@ public class PropertyPlaceHolderSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void propertyOnly() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("server.port", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("server.port");
|
||||
assertThat(tokens.size()).isEqualTo(1);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 11, "property", new String[0]));
|
||||
}
|
||||
|
||||
@Test
|
||||
void propertyWithEmptyDefaulValue() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("server.port:", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("server.port:");
|
||||
assertThat(tokens.size()).isEqualTo(3);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 11, "property", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(11, 12, "operator", new String[0]));
|
||||
@@ -41,7 +41,7 @@ public class PropertyPlaceHolderSemanticTokensTest {
|
||||
@Test
|
||||
void error_1() {
|
||||
provider = new PropertyPlaceHolderSemanticTokens(Optional.empty());
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("server.:", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("server.:");
|
||||
assertThat(tokens.size()).isEqualTo(3);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "property", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(6, 7, "property", new String[0]));
|
||||
@@ -51,7 +51,7 @@ public class PropertyPlaceHolderSemanticTokensTest {
|
||||
@Test
|
||||
void error_2() {
|
||||
provider = new PropertyPlaceHolderSemanticTokens(Optional.empty());
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("server.", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("server.");
|
||||
assertThat(tokens.size()).isEqualTo(2);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "property", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(6, 7, "property", new String[0]));
|
||||
|
||||
@@ -25,7 +25,7 @@ public class SpelSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void simpleCompare() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("1 >= 1", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("1 >= 1");
|
||||
assertThat(tokens.size()).isEqualTo(3);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 1, "number", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(2, 4, "operator", new String[0]));
|
||||
@@ -34,7 +34,7 @@ public class SpelSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void simpleCompareWithOp() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("1 ge 1", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("1 ge 1");
|
||||
assertThat(tokens.size()).isEqualTo(3);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 1, "number", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(2, 4, "keyword", new String[0]));
|
||||
@@ -43,7 +43,7 @@ public class SpelSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void logicalOperators() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("4 > 3 or 15 < 10", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("4 > 3 or 15 < 10");
|
||||
assertThat(tokens.size()).isEqualTo(7);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 1, "number", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(2, 3, "operator", new String[0]));
|
||||
@@ -56,7 +56,7 @@ public class SpelSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void conditionalOperators() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("someBean.someProperty != null ? someBean.someProperty : 'default'", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("someBean.someProperty != null ? someBean.someProperty : 'default'");
|
||||
assertThat(tokens.size()).isEqualTo(11);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 8, "variable", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(8, 9, "operator", new String[0]));
|
||||
@@ -73,7 +73,7 @@ public class SpelSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void regex() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("'invalid alphabetic string #$1' matches '[a-zA-Z\\s]+' ", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("'invalid alphabetic string #$1' matches '[a-zA-Z\\s]+' ");
|
||||
assertThat(tokens.size()).isEqualTo(3);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 31, "string", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(32, 39, "keyword", new String[0]));
|
||||
@@ -82,7 +82,7 @@ public class SpelSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void accessMapObj() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("carPark.carsByDriver['Driver1']", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("carPark.carsByDriver['Driver1']");
|
||||
assertThat(tokens.size()).isEqualTo(6);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 7, "variable", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(7, 8, "operator", new String[0]));
|
||||
@@ -94,7 +94,7 @@ public class SpelSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void accessListItems() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("carPark.cars[0]", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("carPark.cars[0]");
|
||||
assertThat(tokens.size()).isEqualTo(6);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 7, "variable", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(7, 8, "operator", new String[0]));
|
||||
@@ -106,7 +106,7 @@ public class SpelSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void beanReference() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("@vetRepo", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("@vetRepo");
|
||||
assertThat(tokens.size()).isEqualTo(2);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 1, "operator", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(1, 8, "type", new String[0]));
|
||||
@@ -114,7 +114,7 @@ public class SpelSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void contructorAndMethod() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("new String('hello world').toUpperCase()", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("new String('hello world').toUpperCase()");
|
||||
assertThat(tokens.size()).isEqualTo(9);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 3, "keyword", new String[0]));
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(4, 10, "method", new String[0]));
|
||||
@@ -130,7 +130,7 @@ public class SpelSemanticTokensTest {
|
||||
//https://github.com/spring-projects/sts4/issues/1320
|
||||
@Test
|
||||
void inputParameter() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("[1].size().longValue()", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("[1].size().longValue()");
|
||||
assertThat(tokens.size()).isEqualTo(9);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 3, "parameter", new String[0])); // [1]
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(3, 4, "operator", new String[0])); // .
|
||||
@@ -145,7 +145,7 @@ public class SpelSemanticTokensTest {
|
||||
|
||||
@Test
|
||||
void withPropertyPlaceHolder() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("${server.port:8080} == 8080", 0);
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("${server.port:8080} == 8080");
|
||||
assertThat(tokens.size()).isEqualTo(7);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 2, "operator", new String[0])); // ${
|
||||
assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(2, 13, "property", new String[0])); // server.port
|
||||
|
||||
Reference in New Issue
Block a user