CRON parser. Syntax highlighting and validation inside java code.
This commit is contained in:
22
headless-services/commons/jpql/.gitignore
vendored
22
headless-services/commons/jpql/.gitignore
vendored
@@ -1,22 +1,4 @@
|
||||
/antlr-4.13.1.jar
|
||||
/src/main/java/org/springframework/ide/vscode/parser/jpql/Jpql.interp
|
||||
/src/main/java/org/springframework/ide/vscode/parser/jpql/Jpql.tokens
|
||||
/src/main/java/org/springframework/ide/vscode/parser/jpql/JpqlLexer.interp
|
||||
/src/main/java/org/springframework/ide/vscode/parser/jpql/JpqlLexer.tokens
|
||||
/src/main/java/org/springframework/ide/vscode/parser/hql/Hql.interp
|
||||
/src/main/java/org/springframework/ide/vscode/parser/hql/Hql.tokens
|
||||
/src/main/java/org/springframework/ide/vscode/parser/hql/HqlLexer.interp
|
||||
/src/main/java/org/springframework/ide/vscode/parser/hql/HqlLexer.tokens
|
||||
/src/main/java/org/springframework/ide/vscode/parser/mysql/MySqlParser.interp
|
||||
/src/main/java/org/springframework/ide/vscode/parser/mysql/MySqlParser.tokens
|
||||
/src/main/java/org/springframework/ide/vscode/parser/mysql/MySqlLexer.interp
|
||||
/src/main/java/org/springframework/ide/vscode/parser/mysql/MySqlLexer.tokens
|
||||
/src/main/java/org/springframework/ide/vscode/parser/postgresql/PostgreSqlParser.interp
|
||||
/src/main/java/org/springframework/ide/vscode/parser/postgresql/PostgreSqlParser.tokens
|
||||
/src/main/java/org/springframework/ide/vscode/parser/postgresql/PostgreSqlLexer.interp
|
||||
/src/main/java/org/springframework/ide/vscode/parser/postgresql/PostgreSqlLexer.tokens
|
||||
/src/main/java/org/springframework/ide/vscode/parser/spel/SpelParser.interp
|
||||
/src/main/java/org/springframework/ide/vscode/parser/spel/SpelParser.tokens
|
||||
/src/main/java/org/springframework/ide/vscode/parser/spel/SpelLexer.interp
|
||||
/src/main/java/org/springframework/ide/vscode/parser/spel/SpelLexer.tokens
|
||||
/src/main/java/org/springframework/ide/vscode/**/*.interp
|
||||
/src/main/java/org/springframework/ide/vscode/**/*.tokens
|
||||
/target
|
||||
|
||||
@@ -11,4 +11,5 @@ java -jar ${workdir}/antlr-${ANTLR_VERSION}.jar Hql.g4 -o ${workdir}/src/main/ja
|
||||
java -jar ${workdir}/antlr-${ANTLR_VERSION}.jar MySqlLexer.g4 MySqlParser.g4 -o ${workdir}/src/main/java/org/springframework/ide/vscode/parser/mysql -package org.springframework.ide.vscode.parser.mysql
|
||||
java -jar ${workdir}/antlr-${ANTLR_VERSION}.jar SpelLexer.g4 SpelParser.g4 -o ${workdir}/src/main/java/org/springframework/ide/vscode/parser/spel -package org.springframework.ide.vscode.parser.spel
|
||||
java -jar ${workdir}/antlr-${ANTLR_VERSION}.jar PostgreSqlLexer.g4 PostgreSqlParser.g4 -o ${workdir}/src/main/java/org/springframework/ide/vscode/parser/postgresql -package org.springframework.ide.vscode.parser.postgresql
|
||||
java -jar ${workdir}/antlr-${ANTLR_VERSION}.jar CronLexer.g4 CronParser.g4 -o ${workdir}/src/main/java/org/springframework/ide/vscode/parser/cron -package org.springframework.ide.vscode.parser.cron
|
||||
|
||||
|
||||
71
headless-services/commons/jpql/grammars/CronLexer.g4
Normal file
71
headless-services/commons/jpql/grammars/CronLexer.g4
Normal file
@@ -0,0 +1,71 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
*******************************************************************************/
|
||||
|
||||
lexer grammar CronLexer;
|
||||
|
||||
WS
|
||||
: [ \t\r\n]+
|
||||
;
|
||||
|
||||
STAR : '*';
|
||||
QUESTION : '?';
|
||||
DASH : '-';
|
||||
SLASH : '/';
|
||||
COMMA : ',';
|
||||
L : 'L';
|
||||
W : 'W';
|
||||
LW : 'LW';
|
||||
TAG : '#';
|
||||
|
||||
INT
|
||||
: DIGIT+
|
||||
;
|
||||
|
||||
MON: 'MON';
|
||||
TUE: 'TUE';
|
||||
WED: 'WED';
|
||||
THU: 'THU';
|
||||
FRI: 'FRI';
|
||||
SAT: 'SAT';
|
||||
SUN: 'SUN';
|
||||
|
||||
JAN: 'JAN';
|
||||
FEB: 'FEB';
|
||||
MAR: 'MAR';
|
||||
APR: 'APR';
|
||||
MAY: 'MAY';
|
||||
JUN: 'JUN';
|
||||
JUL: 'JUL';
|
||||
AUG: 'AUG';
|
||||
SEP: 'SEP';
|
||||
OCT: 'OCT';
|
||||
NOV: 'NOV';
|
||||
DEC: 'DEC';
|
||||
|
||||
IDENTIFIER
|
||||
: (ALPHABETIC | '_' )* (ALPHABETIC_NO_L | '_')
|
||||
;
|
||||
|
||||
MACRO
|
||||
: '@' (ALPHABETIC | '_') (ALPHABETIC | DIGIT | '_' | '$')*
|
||||
;
|
||||
|
||||
fragment ALPHABETIC
|
||||
: [a-zA-Z]
|
||||
;
|
||||
|
||||
fragment ALPHABETIC_NO_L
|
||||
: [a-zA-KM-Z]
|
||||
;
|
||||
|
||||
fragment DIGIT
|
||||
: [0-9]
|
||||
;
|
||||
110
headless-services/commons/jpql/grammars/CronParser.g4
Normal file
110
headless-services/commons/jpql/grammars/CronParser.g4
Normal file
@@ -0,0 +1,110 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
*******************************************************************************/
|
||||
parser grammar CronParser;
|
||||
options { tokenVocab=CronLexer; }
|
||||
|
||||
cronExpression
|
||||
: WS* secondsElement WS+ minutesElement WS+ hoursElement WS+ daysElement WS+ monthsElement WS+ daysOfWeekElement WS*
|
||||
| WS* MACRO WS*
|
||||
;
|
||||
|
||||
secondsElement
|
||||
: cronElement
|
||||
;
|
||||
|
||||
minutesElement
|
||||
: cronElement
|
||||
;
|
||||
|
||||
hoursElement
|
||||
: cronElement
|
||||
;
|
||||
|
||||
daysElement
|
||||
: nearestWeekDayToDayOfMonthElement
|
||||
| lastDayOfMonthElement
|
||||
| cronElement
|
||||
;
|
||||
|
||||
monthsElement
|
||||
: cronElement
|
||||
;
|
||||
|
||||
daysOfWeekElement
|
||||
: nthDayOfWeekElement
|
||||
| lastDayOfWeekElement
|
||||
| cronElement
|
||||
;
|
||||
|
||||
cronElement
|
||||
: rangeCronList
|
||||
| periodicCronElement
|
||||
;
|
||||
|
||||
rangeCronElement
|
||||
: terminalCronElement (DASH (INT | weekdayLiteral | monthLiteral))*
|
||||
;
|
||||
|
||||
terminalCronElement
|
||||
: ( INT | weekdayLiteral | monthLiteral | STAR | QUESTION )
|
||||
;
|
||||
|
||||
periodicCronElement
|
||||
: terminalCronElement SLASH rangeCronList
|
||||
;
|
||||
|
||||
rangeCronList
|
||||
: rangeCronElement (COMMA rangeCronElement)*
|
||||
;
|
||||
|
||||
nthDayOfWeekElement
|
||||
: INT TAG INT
|
||||
| weekdayLiteral TAG INT
|
||||
;
|
||||
|
||||
lastDayOfWeekElement
|
||||
: INT L
|
||||
| weekdayLiteral L
|
||||
;
|
||||
|
||||
nearestWeekDayToDayOfMonthElement
|
||||
: INT W
|
||||
;
|
||||
|
||||
lastDayOfMonthElement
|
||||
: L (DASH INT)?
|
||||
| LW
|
||||
;
|
||||
|
||||
weekdayLiteral
|
||||
: MON
|
||||
| TUE
|
||||
| WED
|
||||
| THU
|
||||
| FRI
|
||||
| SAT
|
||||
| SUN
|
||||
;
|
||||
|
||||
monthLiteral
|
||||
: JAN
|
||||
| FEB
|
||||
| MAR
|
||||
| APR
|
||||
| MAY
|
||||
| JUN
|
||||
| JUL
|
||||
| AUG
|
||||
| SEP
|
||||
| OCT
|
||||
| NOV
|
||||
| DEC
|
||||
;
|
||||
@@ -0,0 +1,253 @@
|
||||
// Generated from CronLexer.g4 by ANTLR 4.13.1
|
||||
package org.springframework.ide.vscode.parser.cron;
|
||||
import org.antlr.v4.runtime.Lexer;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.TokenStream;
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.antlr.v4.runtime.misc.*;
|
||||
|
||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue", "this-escape"})
|
||||
public class CronLexer extends Lexer {
|
||||
static { RuntimeMetaData.checkVersion("4.13.1", RuntimeMetaData.VERSION); }
|
||||
|
||||
protected static final DFA[] _decisionToDFA;
|
||||
protected static final PredictionContextCache _sharedContextCache =
|
||||
new PredictionContextCache();
|
||||
public static final int
|
||||
WS=1, STAR=2, QUESTION=3, DASH=4, SLASH=5, COMMA=6, L=7, W=8, LW=9, TAG=10,
|
||||
INT=11, MON=12, TUE=13, WED=14, THU=15, FRI=16, SAT=17, SUN=18, JAN=19,
|
||||
FEB=20, MAR=21, APR=22, MAY=23, JUN=24, JUL=25, AUG=26, SEP=27, OCT=28,
|
||||
NOV=29, DEC=30, IDENTIFIER=31, MACRO=32;
|
||||
public static String[] channelNames = {
|
||||
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
|
||||
};
|
||||
|
||||
public static String[] modeNames = {
|
||||
"DEFAULT_MODE"
|
||||
};
|
||||
|
||||
private static String[] makeRuleNames() {
|
||||
return new String[] {
|
||||
"WS", "STAR", "QUESTION", "DASH", "SLASH", "COMMA", "L", "W", "LW", "TAG",
|
||||
"INT", "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN", "JAN", "FEB",
|
||||
"MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC",
|
||||
"IDENTIFIER", "MACRO", "ALPHABETIC", "ALPHABETIC_NO_L", "DIGIT"
|
||||
};
|
||||
}
|
||||
public static final String[] ruleNames = makeRuleNames();
|
||||
|
||||
private static String[] makeLiteralNames() {
|
||||
return new String[] {
|
||||
null, null, "'*'", "'?'", "'-'", "'/'", "','", "'L'", "'W'", "'LW'",
|
||||
"'#'", null, "'MON'", "'TUE'", "'WED'", "'THU'", "'FRI'", "'SAT'", "'SUN'",
|
||||
"'JAN'", "'FEB'", "'MAR'", "'APR'", "'MAY'", "'JUN'", "'JUL'", "'AUG'",
|
||||
"'SEP'", "'OCT'", "'NOV'", "'DEC'"
|
||||
};
|
||||
}
|
||||
private static final String[] _LITERAL_NAMES = makeLiteralNames();
|
||||
private static String[] makeSymbolicNames() {
|
||||
return new String[] {
|
||||
null, "WS", "STAR", "QUESTION", "DASH", "SLASH", "COMMA", "L", "W", "LW",
|
||||
"TAG", "INT", "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN", "JAN",
|
||||
"FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV",
|
||||
"DEC", "IDENTIFIER", "MACRO"
|
||||
};
|
||||
}
|
||||
private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
|
||||
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #VOCABULARY} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String[] tokenNames;
|
||||
static {
|
||||
tokenNames = new String[_SYMBOLIC_NAMES.length];
|
||||
for (int i = 0; i < tokenNames.length; i++) {
|
||||
tokenNames[i] = VOCABULARY.getLiteralName(i);
|
||||
if (tokenNames[i] == null) {
|
||||
tokenNames[i] = VOCABULARY.getSymbolicName(i);
|
||||
}
|
||||
|
||||
if (tokenNames[i] == null) {
|
||||
tokenNames[i] = "<INVALID>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String[] getTokenNames() {
|
||||
return tokenNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public Vocabulary getVocabulary() {
|
||||
return VOCABULARY;
|
||||
}
|
||||
|
||||
|
||||
public CronLexer(CharStream input) {
|
||||
super(input);
|
||||
_interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGrammarFileName() { return "CronLexer.g4"; }
|
||||
|
||||
@Override
|
||||
public String[] getRuleNames() { return ruleNames; }
|
||||
|
||||
@Override
|
||||
public String getSerializedATN() { return _serializedATN; }
|
||||
|
||||
@Override
|
||||
public String[] getChannelNames() { return channelNames; }
|
||||
|
||||
@Override
|
||||
public String[] getModeNames() { return modeNames; }
|
||||
|
||||
@Override
|
||||
public ATN getATN() { return _ATN; }
|
||||
|
||||
public static final String _serializedATN =
|
||||
"\u0004\u0000 \u00ce\u0006\uffff\uffff\u0002\u0000\u0007\u0000\u0002\u0001"+
|
||||
"\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004"+
|
||||
"\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007"+
|
||||
"\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002\u000b"+
|
||||
"\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e\u0002"+
|
||||
"\u000f\u0007\u000f\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011\u0002"+
|
||||
"\u0012\u0007\u0012\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014\u0002"+
|
||||
"\u0015\u0007\u0015\u0002\u0016\u0007\u0016\u0002\u0017\u0007\u0017\u0002"+
|
||||
"\u0018\u0007\u0018\u0002\u0019\u0007\u0019\u0002\u001a\u0007\u001a\u0002"+
|
||||
"\u001b\u0007\u001b\u0002\u001c\u0007\u001c\u0002\u001d\u0007\u001d\u0002"+
|
||||
"\u001e\u0007\u001e\u0002\u001f\u0007\u001f\u0002 \u0007 \u0002!\u0007"+
|
||||
"!\u0002\"\u0007\"\u0001\u0000\u0004\u0000I\b\u0000\u000b\u0000\f\u0000"+
|
||||
"J\u0001\u0001\u0001\u0001\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003"+
|
||||
"\u0001\u0004\u0001\u0004\u0001\u0005\u0001\u0005\u0001\u0006\u0001\u0006"+
|
||||
"\u0001\u0007\u0001\u0007\u0001\b\u0001\b\u0001\b\u0001\t\u0001\t\u0001"+
|
||||
"\n\u0004\na\b\n\u000b\n\f\nb\u0001\u000b\u0001\u000b\u0001\u000b\u0001"+
|
||||
"\u000b\u0001\f\u0001\f\u0001\f\u0001\f\u0001\r\u0001\r\u0001\r\u0001\r"+
|
||||
"\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000f\u0001\u000f"+
|
||||
"\u0001\u000f\u0001\u000f\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010"+
|
||||
"\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0012\u0001\u0012"+
|
||||
"\u0001\u0012\u0001\u0012\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013"+
|
||||
"\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0015\u0001\u0015"+
|
||||
"\u0001\u0015\u0001\u0015\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016"+
|
||||
"\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0018\u0001\u0018"+
|
||||
"\u0001\u0018\u0001\u0018\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019"+
|
||||
"\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001b\u0001\u001b"+
|
||||
"\u0001\u001b\u0001\u001b\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001c"+
|
||||
"\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001e\u0001\u001e"+
|
||||
"\u0005\u001e\u00b3\b\u001e\n\u001e\f\u001e\u00b6\t\u001e\u0001\u001e\u0001"+
|
||||
"\u001e\u0003\u001e\u00ba\b\u001e\u0001\u001f\u0001\u001f\u0001\u001f\u0003"+
|
||||
"\u001f\u00bf\b\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0005\u001f\u00c4"+
|
||||
"\b\u001f\n\u001f\f\u001f\u00c7\t\u001f\u0001 \u0001 \u0001!\u0001!\u0001"+
|
||||
"\"\u0001\"\u0000\u0000#\u0001\u0001\u0003\u0002\u0005\u0003\u0007\u0004"+
|
||||
"\t\u0005\u000b\u0006\r\u0007\u000f\b\u0011\t\u0013\n\u0015\u000b\u0017"+
|
||||
"\f\u0019\r\u001b\u000e\u001d\u000f\u001f\u0010!\u0011#\u0012%\u0013\'"+
|
||||
"\u0014)\u0015+\u0016-\u0017/\u00181\u00193\u001a5\u001b7\u001c9\u001d"+
|
||||
";\u001e=\u001f? A\u0000C\u0000E\u0000\u0001\u0000\u0005\u0003\u0000\t"+
|
||||
"\n\r\r \u0002\u0000$$__\u0002\u0000AZaz\u0003\u0000AKMZaz\u0001\u0000"+
|
||||
"09\u00d3\u0000\u0001\u0001\u0000\u0000\u0000\u0000\u0003\u0001\u0000\u0000"+
|
||||
"\u0000\u0000\u0005\u0001\u0000\u0000\u0000\u0000\u0007\u0001\u0000\u0000"+
|
||||
"\u0000\u0000\t\u0001\u0000\u0000\u0000\u0000\u000b\u0001\u0000\u0000\u0000"+
|
||||
"\u0000\r\u0001\u0000\u0000\u0000\u0000\u000f\u0001\u0000\u0000\u0000\u0000"+
|
||||
"\u0011\u0001\u0000\u0000\u0000\u0000\u0013\u0001\u0000\u0000\u0000\u0000"+
|
||||
"\u0015\u0001\u0000\u0000\u0000\u0000\u0017\u0001\u0000\u0000\u0000\u0000"+
|
||||
"\u0019\u0001\u0000\u0000\u0000\u0000\u001b\u0001\u0000\u0000\u0000\u0000"+
|
||||
"\u001d\u0001\u0000\u0000\u0000\u0000\u001f\u0001\u0000\u0000\u0000\u0000"+
|
||||
"!\u0001\u0000\u0000\u0000\u0000#\u0001\u0000\u0000\u0000\u0000%\u0001"+
|
||||
"\u0000\u0000\u0000\u0000\'\u0001\u0000\u0000\u0000\u0000)\u0001\u0000"+
|
||||
"\u0000\u0000\u0000+\u0001\u0000\u0000\u0000\u0000-\u0001\u0000\u0000\u0000"+
|
||||
"\u0000/\u0001\u0000\u0000\u0000\u00001\u0001\u0000\u0000\u0000\u00003"+
|
||||
"\u0001\u0000\u0000\u0000\u00005\u0001\u0000\u0000\u0000\u00007\u0001\u0000"+
|
||||
"\u0000\u0000\u00009\u0001\u0000\u0000\u0000\u0000;\u0001\u0000\u0000\u0000"+
|
||||
"\u0000=\u0001\u0000\u0000\u0000\u0000?\u0001\u0000\u0000\u0000\u0001H"+
|
||||
"\u0001\u0000\u0000\u0000\u0003L\u0001\u0000\u0000\u0000\u0005N\u0001\u0000"+
|
||||
"\u0000\u0000\u0007P\u0001\u0000\u0000\u0000\tR\u0001\u0000\u0000\u0000"+
|
||||
"\u000bT\u0001\u0000\u0000\u0000\rV\u0001\u0000\u0000\u0000\u000fX\u0001"+
|
||||
"\u0000\u0000\u0000\u0011Z\u0001\u0000\u0000\u0000\u0013]\u0001\u0000\u0000"+
|
||||
"\u0000\u0015`\u0001\u0000\u0000\u0000\u0017d\u0001\u0000\u0000\u0000\u0019"+
|
||||
"h\u0001\u0000\u0000\u0000\u001bl\u0001\u0000\u0000\u0000\u001dp\u0001"+
|
||||
"\u0000\u0000\u0000\u001ft\u0001\u0000\u0000\u0000!x\u0001\u0000\u0000"+
|
||||
"\u0000#|\u0001\u0000\u0000\u0000%\u0080\u0001\u0000\u0000\u0000\'\u0084"+
|
||||
"\u0001\u0000\u0000\u0000)\u0088\u0001\u0000\u0000\u0000+\u008c\u0001\u0000"+
|
||||
"\u0000\u0000-\u0090\u0001\u0000\u0000\u0000/\u0094\u0001\u0000\u0000\u0000"+
|
||||
"1\u0098\u0001\u0000\u0000\u00003\u009c\u0001\u0000\u0000\u00005\u00a0"+
|
||||
"\u0001\u0000\u0000\u00007\u00a4\u0001\u0000\u0000\u00009\u00a8\u0001\u0000"+
|
||||
"\u0000\u0000;\u00ac\u0001\u0000\u0000\u0000=\u00b4\u0001\u0000\u0000\u0000"+
|
||||
"?\u00bb\u0001\u0000\u0000\u0000A\u00c8\u0001\u0000\u0000\u0000C\u00ca"+
|
||||
"\u0001\u0000\u0000\u0000E\u00cc\u0001\u0000\u0000\u0000GI\u0007\u0000"+
|
||||
"\u0000\u0000HG\u0001\u0000\u0000\u0000IJ\u0001\u0000\u0000\u0000JH\u0001"+
|
||||
"\u0000\u0000\u0000JK\u0001\u0000\u0000\u0000K\u0002\u0001\u0000\u0000"+
|
||||
"\u0000LM\u0005*\u0000\u0000M\u0004\u0001\u0000\u0000\u0000NO\u0005?\u0000"+
|
||||
"\u0000O\u0006\u0001\u0000\u0000\u0000PQ\u0005-\u0000\u0000Q\b\u0001\u0000"+
|
||||
"\u0000\u0000RS\u0005/\u0000\u0000S\n\u0001\u0000\u0000\u0000TU\u0005,"+
|
||||
"\u0000\u0000U\f\u0001\u0000\u0000\u0000VW\u0005L\u0000\u0000W\u000e\u0001"+
|
||||
"\u0000\u0000\u0000XY\u0005W\u0000\u0000Y\u0010\u0001\u0000\u0000\u0000"+
|
||||
"Z[\u0005L\u0000\u0000[\\\u0005W\u0000\u0000\\\u0012\u0001\u0000\u0000"+
|
||||
"\u0000]^\u0005#\u0000\u0000^\u0014\u0001\u0000\u0000\u0000_a\u0003E\""+
|
||||
"\u0000`_\u0001\u0000\u0000\u0000ab\u0001\u0000\u0000\u0000b`\u0001\u0000"+
|
||||
"\u0000\u0000bc\u0001\u0000\u0000\u0000c\u0016\u0001\u0000\u0000\u0000"+
|
||||
"de\u0005M\u0000\u0000ef\u0005O\u0000\u0000fg\u0005N\u0000\u0000g\u0018"+
|
||||
"\u0001\u0000\u0000\u0000hi\u0005T\u0000\u0000ij\u0005U\u0000\u0000jk\u0005"+
|
||||
"E\u0000\u0000k\u001a\u0001\u0000\u0000\u0000lm\u0005W\u0000\u0000mn\u0005"+
|
||||
"E\u0000\u0000no\u0005D\u0000\u0000o\u001c\u0001\u0000\u0000\u0000pq\u0005"+
|
||||
"T\u0000\u0000qr\u0005H\u0000\u0000rs\u0005U\u0000\u0000s\u001e\u0001\u0000"+
|
||||
"\u0000\u0000tu\u0005F\u0000\u0000uv\u0005R\u0000\u0000vw\u0005I\u0000"+
|
||||
"\u0000w \u0001\u0000\u0000\u0000xy\u0005S\u0000\u0000yz\u0005A\u0000\u0000"+
|
||||
"z{\u0005T\u0000\u0000{\"\u0001\u0000\u0000\u0000|}\u0005S\u0000\u0000"+
|
||||
"}~\u0005U\u0000\u0000~\u007f\u0005N\u0000\u0000\u007f$\u0001\u0000\u0000"+
|
||||
"\u0000\u0080\u0081\u0005J\u0000\u0000\u0081\u0082\u0005A\u0000\u0000\u0082"+
|
||||
"\u0083\u0005N\u0000\u0000\u0083&\u0001\u0000\u0000\u0000\u0084\u0085\u0005"+
|
||||
"F\u0000\u0000\u0085\u0086\u0005E\u0000\u0000\u0086\u0087\u0005B\u0000"+
|
||||
"\u0000\u0087(\u0001\u0000\u0000\u0000\u0088\u0089\u0005M\u0000\u0000\u0089"+
|
||||
"\u008a\u0005A\u0000\u0000\u008a\u008b\u0005R\u0000\u0000\u008b*\u0001"+
|
||||
"\u0000\u0000\u0000\u008c\u008d\u0005A\u0000\u0000\u008d\u008e\u0005P\u0000"+
|
||||
"\u0000\u008e\u008f\u0005R\u0000\u0000\u008f,\u0001\u0000\u0000\u0000\u0090"+
|
||||
"\u0091\u0005M\u0000\u0000\u0091\u0092\u0005A\u0000\u0000\u0092\u0093\u0005"+
|
||||
"Y\u0000\u0000\u0093.\u0001\u0000\u0000\u0000\u0094\u0095\u0005J\u0000"+
|
||||
"\u0000\u0095\u0096\u0005U\u0000\u0000\u0096\u0097\u0005N\u0000\u0000\u0097"+
|
||||
"0\u0001\u0000\u0000\u0000\u0098\u0099\u0005J\u0000\u0000\u0099\u009a\u0005"+
|
||||
"U\u0000\u0000\u009a\u009b\u0005L\u0000\u0000\u009b2\u0001\u0000\u0000"+
|
||||
"\u0000\u009c\u009d\u0005A\u0000\u0000\u009d\u009e\u0005U\u0000\u0000\u009e"+
|
||||
"\u009f\u0005G\u0000\u0000\u009f4\u0001\u0000\u0000\u0000\u00a0\u00a1\u0005"+
|
||||
"S\u0000\u0000\u00a1\u00a2\u0005E\u0000\u0000\u00a2\u00a3\u0005P\u0000"+
|
||||
"\u0000\u00a36\u0001\u0000\u0000\u0000\u00a4\u00a5\u0005O\u0000\u0000\u00a5"+
|
||||
"\u00a6\u0005C\u0000\u0000\u00a6\u00a7\u0005T\u0000\u0000\u00a78\u0001"+
|
||||
"\u0000\u0000\u0000\u00a8\u00a9\u0005N\u0000\u0000\u00a9\u00aa\u0005O\u0000"+
|
||||
"\u0000\u00aa\u00ab\u0005V\u0000\u0000\u00ab:\u0001\u0000\u0000\u0000\u00ac"+
|
||||
"\u00ad\u0005D\u0000\u0000\u00ad\u00ae\u0005E\u0000\u0000\u00ae\u00af\u0005"+
|
||||
"C\u0000\u0000\u00af<\u0001\u0000\u0000\u0000\u00b0\u00b3\u0003A \u0000"+
|
||||
"\u00b1\u00b3\u0005_\u0000\u0000\u00b2\u00b0\u0001\u0000\u0000\u0000\u00b2"+
|
||||
"\u00b1\u0001\u0000\u0000\u0000\u00b3\u00b6\u0001\u0000\u0000\u0000\u00b4"+
|
||||
"\u00b2\u0001\u0000\u0000\u0000\u00b4\u00b5\u0001\u0000\u0000\u0000\u00b5"+
|
||||
"\u00b9\u0001\u0000\u0000\u0000\u00b6\u00b4\u0001\u0000\u0000\u0000\u00b7"+
|
||||
"\u00ba\u0003C!\u0000\u00b8\u00ba\u0005_\u0000\u0000\u00b9\u00b7\u0001"+
|
||||
"\u0000\u0000\u0000\u00b9\u00b8\u0001\u0000\u0000\u0000\u00ba>\u0001\u0000"+
|
||||
"\u0000\u0000\u00bb\u00be\u0005@\u0000\u0000\u00bc\u00bf\u0003A \u0000"+
|
||||
"\u00bd\u00bf\u0005_\u0000\u0000\u00be\u00bc\u0001\u0000\u0000\u0000\u00be"+
|
||||
"\u00bd\u0001\u0000\u0000\u0000\u00bf\u00c5\u0001\u0000\u0000\u0000\u00c0"+
|
||||
"\u00c4\u0003A \u0000\u00c1\u00c4\u0003E\"\u0000\u00c2\u00c4\u0007\u0001"+
|
||||
"\u0000\u0000\u00c3\u00c0\u0001\u0000\u0000\u0000\u00c3\u00c1\u0001\u0000"+
|
||||
"\u0000\u0000\u00c3\u00c2\u0001\u0000\u0000\u0000\u00c4\u00c7\u0001\u0000"+
|
||||
"\u0000\u0000\u00c5\u00c3\u0001\u0000\u0000\u0000\u00c5\u00c6\u0001\u0000"+
|
||||
"\u0000\u0000\u00c6@\u0001\u0000\u0000\u0000\u00c7\u00c5\u0001\u0000\u0000"+
|
||||
"\u0000\u00c8\u00c9\u0007\u0002\u0000\u0000\u00c9B\u0001\u0000\u0000\u0000"+
|
||||
"\u00ca\u00cb\u0007\u0003\u0000\u0000\u00cbD\u0001\u0000\u0000\u0000\u00cc"+
|
||||
"\u00cd\u0007\u0004\u0000\u0000\u00cdF\u0001\u0000\u0000\u0000\t\u0000"+
|
||||
"Jb\u00b2\u00b4\u00b9\u00be\u00c3\u00c5\u0000";
|
||||
public static final ATN _ATN =
|
||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||
static {
|
||||
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
|
||||
for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
|
||||
_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,256 @@
|
||||
// Generated from CronParser.g4 by ANTLR 4.13.1
|
||||
package org.springframework.ide.vscode.parser.cron;
|
||||
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ErrorNode;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
|
||||
/**
|
||||
* This class provides an empty implementation of {@link CronParserListener},
|
||||
* which can be extended to create a listener which only needs to handle a subset
|
||||
* of the available methods.
|
||||
*/
|
||||
@SuppressWarnings("CheckReturnValue")
|
||||
public class CronParserBaseListener implements CronParserListener {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterCronExpression(CronParser.CronExpressionContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitCronExpression(CronParser.CronExpressionContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterSecondsElement(CronParser.SecondsElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitSecondsElement(CronParser.SecondsElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterMinutesElement(CronParser.MinutesElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitMinutesElement(CronParser.MinutesElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterHoursElement(CronParser.HoursElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitHoursElement(CronParser.HoursElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterDaysElement(CronParser.DaysElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitDaysElement(CronParser.DaysElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterMonthsElement(CronParser.MonthsElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitMonthsElement(CronParser.MonthsElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterDaysOfWeekElement(CronParser.DaysOfWeekElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitDaysOfWeekElement(CronParser.DaysOfWeekElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterCronElement(CronParser.CronElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitCronElement(CronParser.CronElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterRangeCronElement(CronParser.RangeCronElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitRangeCronElement(CronParser.RangeCronElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterTerminalCronElement(CronParser.TerminalCronElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitTerminalCronElement(CronParser.TerminalCronElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterPeriodicCronElement(CronParser.PeriodicCronElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitPeriodicCronElement(CronParser.PeriodicCronElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterRangeCronList(CronParser.RangeCronListContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitRangeCronList(CronParser.RangeCronListContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterNthDayOfWeekElement(CronParser.NthDayOfWeekElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitNthDayOfWeekElement(CronParser.NthDayOfWeekElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterLastDayOfWeekElement(CronParser.LastDayOfWeekElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitLastDayOfWeekElement(CronParser.LastDayOfWeekElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterNearestWeekDayToDayOfMonthElement(CronParser.NearestWeekDayToDayOfMonthElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitNearestWeekDayToDayOfMonthElement(CronParser.NearestWeekDayToDayOfMonthElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterLastDayOfMonthElement(CronParser.LastDayOfMonthElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitLastDayOfMonthElement(CronParser.LastDayOfMonthElementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterWeekdayLiteral(CronParser.WeekdayLiteralContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitWeekdayLiteral(CronParser.WeekdayLiteralContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterMonthLiteral(CronParser.MonthLiteralContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitMonthLiteral(CronParser.MonthLiteralContext ctx) { }
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterEveryRule(ParserRuleContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitEveryRule(ParserRuleContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void visitTerminal(TerminalNode node) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void visitErrorNode(ErrorNode node) { }
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
// Generated from CronParser.g4 by ANTLR 4.13.1
|
||||
package org.springframework.ide.vscode.parser.cron;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeListener;
|
||||
|
||||
/**
|
||||
* This interface defines a complete listener for a parse tree produced by
|
||||
* {@link CronParser}.
|
||||
*/
|
||||
public interface CronParserListener extends ParseTreeListener {
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CronParser#cronExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterCronExpression(CronParser.CronExpressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CronParser#cronExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitCronExpression(CronParser.CronExpressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CronParser#secondsElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterSecondsElement(CronParser.SecondsElementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CronParser#secondsElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitSecondsElement(CronParser.SecondsElementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CronParser#minutesElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterMinutesElement(CronParser.MinutesElementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CronParser#minutesElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitMinutesElement(CronParser.MinutesElementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CronParser#hoursElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterHoursElement(CronParser.HoursElementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CronParser#hoursElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitHoursElement(CronParser.HoursElementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CronParser#daysElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterDaysElement(CronParser.DaysElementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CronParser#daysElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitDaysElement(CronParser.DaysElementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CronParser#monthsElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterMonthsElement(CronParser.MonthsElementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CronParser#monthsElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitMonthsElement(CronParser.MonthsElementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CronParser#daysOfWeekElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterDaysOfWeekElement(CronParser.DaysOfWeekElementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CronParser#daysOfWeekElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitDaysOfWeekElement(CronParser.DaysOfWeekElementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CronParser#cronElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterCronElement(CronParser.CronElementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CronParser#cronElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitCronElement(CronParser.CronElementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CronParser#rangeCronElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterRangeCronElement(CronParser.RangeCronElementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CronParser#rangeCronElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitRangeCronElement(CronParser.RangeCronElementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CronParser#terminalCronElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterTerminalCronElement(CronParser.TerminalCronElementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CronParser#terminalCronElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitTerminalCronElement(CronParser.TerminalCronElementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CronParser#periodicCronElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterPeriodicCronElement(CronParser.PeriodicCronElementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CronParser#periodicCronElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitPeriodicCronElement(CronParser.PeriodicCronElementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CronParser#rangeCronList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterRangeCronList(CronParser.RangeCronListContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CronParser#rangeCronList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitRangeCronList(CronParser.RangeCronListContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CronParser#nthDayOfWeekElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterNthDayOfWeekElement(CronParser.NthDayOfWeekElementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CronParser#nthDayOfWeekElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitNthDayOfWeekElement(CronParser.NthDayOfWeekElementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CronParser#lastDayOfWeekElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterLastDayOfWeekElement(CronParser.LastDayOfWeekElementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CronParser#lastDayOfWeekElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitLastDayOfWeekElement(CronParser.LastDayOfWeekElementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CronParser#nearestWeekDayToDayOfMonthElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterNearestWeekDayToDayOfMonthElement(CronParser.NearestWeekDayToDayOfMonthElementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CronParser#nearestWeekDayToDayOfMonthElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitNearestWeekDayToDayOfMonthElement(CronParser.NearestWeekDayToDayOfMonthElementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CronParser#lastDayOfMonthElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterLastDayOfMonthElement(CronParser.LastDayOfMonthElementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CronParser#lastDayOfMonthElement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitLastDayOfMonthElement(CronParser.LastDayOfMonthElementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CronParser#weekdayLiteral}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterWeekdayLiteral(CronParser.WeekdayLiteralContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CronParser#weekdayLiteral}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitWeekdayLiteral(CronParser.WeekdayLiteralContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CronParser#monthLiteral}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterMonthLiteral(CronParser.MonthLiteralContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CronParser#monthLiteral}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitMonthLiteral(CronParser.MonthLiteralContext ctx);
|
||||
}
|
||||
@@ -61,6 +61,11 @@
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-util</artifactId>
|
||||
<version>${dependencies.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-yaml</artifactId>
|
||||
@@ -196,6 +201,11 @@
|
||||
<version>${dependencies.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-util</artifactId>
|
||||
<version>1.57.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*******************************************************************************
|
||||
* 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.app;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.ide.vscode.boot.java.cron.CronReconciler;
|
||||
import org.springframework.ide.vscode.boot.java.cron.CronSemanticTokens;
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class CronConfig {
|
||||
|
||||
@Bean
|
||||
CronSemanticTokens cronSemanticTokens() {
|
||||
return new CronSemanticTokens();
|
||||
}
|
||||
|
||||
@Bean
|
||||
CronReconciler cronReconciler() {
|
||||
return new CronReconciler();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,6 +15,10 @@ import java.util.Optional;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.ide.vscode.boot.java.cron.CronReconciler;
|
||||
import org.springframework.ide.vscode.boot.java.cron.CronSemanticTokens;
|
||||
import org.springframework.ide.vscode.boot.java.cron.JdtCronReconciler;
|
||||
import org.springframework.ide.vscode.boot.java.cron.JdtCronSemanticTokensProvider;
|
||||
import org.springframework.ide.vscode.boot.java.data.jpa.queries.HqlSemanticTokens;
|
||||
import org.springframework.ide.vscode.boot.java.data.jpa.queries.JdtDataQuerySemanticTokensProvider;
|
||||
import org.springframework.ide.vscode.boot.java.data.jpa.queries.JpqlSemanticTokens;
|
||||
@@ -126,6 +130,10 @@ public class JdtConfig {
|
||||
return new JdtDataQuerySemanticTokensProvider(jpqlProvider, hqlProvider, supportState, spelSemanticTokens);
|
||||
}
|
||||
|
||||
@Bean JdtCronSemanticTokensProvider jdtCronSemanticTokensProvider(CronSemanticTokens cronProvider) {
|
||||
return new JdtCronSemanticTokensProvider(cronProvider);
|
||||
}
|
||||
|
||||
@Bean QueryJdtAstReconciler dataQueryReconciler(
|
||||
@Qualifier("hqlReconciler") Reconciler hqlReconciler,
|
||||
@Qualifier("jpqlReconciler") Reconciler jpqlReconciler,
|
||||
@@ -148,5 +156,9 @@ public class JdtConfig {
|
||||
@Bean ImplicitWebAnnotationNamesReconciler implicitWebAnnotationNamesReconciler(SimpleLanguageServer server) {
|
||||
return new ImplicitWebAnnotationNamesReconciler(server.getQuickfixRegistry());
|
||||
}
|
||||
|
||||
@Bean JdtCronReconciler jdtCronReconciler(CronReconciler cronReconciler) {
|
||||
return new JdtCronReconciler(cronReconciler);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,7 +38,10 @@ public class SpringProblemCategories {
|
||||
public static final ProblemCategory VERSION_VALIDATION = new ProblemCategory("version-validation", "Versions and Support Ranges",
|
||||
new Toggle("Enablement", EnumSet.of(OFF, ON), ON, "boot-java.validation.java.version-validation"));
|
||||
|
||||
public static final ProblemCategory DATA_QUERY = new ProblemCategory("data-query", "Data Query",
|
||||
public static final ProblemCategory DATA_QUERY = new ProblemCategory("data-query", "Data Queries",
|
||||
new Toggle("Enablement", EnumSet.of(OFF, ON), ON, "boot-java.validation.data-query"));
|
||||
|
||||
public static final ProblemCategory CRON = new ProblemCategory("cron", "CRON Expressions",
|
||||
new Toggle("Enablement", EnumSet.of(OFF, ON), ON, "boot-java.validation.cron"));
|
||||
|
||||
}
|
||||
|
||||
@@ -83,6 +83,8 @@ public class Annotations {
|
||||
public static final String NAMED_JAVAX = "javax.inject.Named";
|
||||
public static final String NAMED_JAKARTA = "jakarta.inject.Named";
|
||||
|
||||
public static final String SCHEDULED = "org.springframework.scheduling.annotation.Scheduled";
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*******************************************************************************
|
||||
* 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.cron;
|
||||
|
||||
import static org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemSeverity.ERROR;
|
||||
|
||||
import org.springframework.ide.vscode.boot.common.SpringProblemCategories;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemCategory;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemSeverity;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
|
||||
public enum CronProblemType implements ProblemType {
|
||||
|
||||
SYNTAX(ERROR, "Syntax", "Cron Expression Syntax"),
|
||||
FIELD(ERROR, "Field", "Cron Expression field");
|
||||
|
||||
private final ProblemSeverity defaultSeverity;
|
||||
private String description;
|
||||
private String label;
|
||||
|
||||
private CronProblemType(ProblemSeverity defaultSeverity, String description) {
|
||||
this(defaultSeverity, description, null);
|
||||
}
|
||||
|
||||
private CronProblemType(ProblemSeverity defaultSeverity, String description, String label) {
|
||||
this.description = description;
|
||||
this.defaultSeverity = defaultSeverity;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProblemSeverity getDefaultSeverity() {
|
||||
return defaultSeverity;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
if (label==null) {
|
||||
label = createDefaultLabel();
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
private String createDefaultLabel() {
|
||||
String label = this.toString().substring(5).toLowerCase().replace('_', ' ');
|
||||
return Character.toUpperCase(label.charAt(0)) + label.substring(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCode() {
|
||||
return name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProblemCategory getCategory() {
|
||||
return SpringProblemCategories.CRON;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
/*******************************************************************************
|
||||
* 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.cron;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.BitSet;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.antlr.v4.runtime.ANTLRErrorListener;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.ConsoleErrorListener;
|
||||
import org.antlr.v4.runtime.Parser;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.RecognitionException;
|
||||
import org.antlr.v4.runtime.Recognizer;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.atn.ATNConfigSet;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
|
||||
import org.antlr.v4.runtime.tree.ErrorNode;
|
||||
import org.antlr.v4.runtime.tree.RuleNode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
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.linetracker.DefaultLineTracker;
|
||||
import org.springframework.ide.vscode.parser.cron.CronLexer;
|
||||
import org.springframework.ide.vscode.parser.cron.CronParser;
|
||||
import org.springframework.ide.vscode.parser.cron.CronParser.DaysElementContext;
|
||||
import org.springframework.ide.vscode.parser.cron.CronParser.DaysOfWeekElementContext;
|
||||
import org.springframework.ide.vscode.parser.cron.CronParser.HoursElementContext;
|
||||
import org.springframework.ide.vscode.parser.cron.CronParser.MinutesElementContext;
|
||||
import org.springframework.ide.vscode.parser.cron.CronParser.MonthsElementContext;
|
||||
import org.springframework.ide.vscode.parser.cron.CronParser.SecondsElementContext;
|
||||
import org.springframework.ide.vscode.parser.cron.CronParserBaseListener;
|
||||
|
||||
public class CronReconciler implements Reconciler {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(CronReconciler.class);
|
||||
|
||||
private Method parseSeconds;
|
||||
private Method parseMinutes;
|
||||
private Method parseHours;
|
||||
private Method parseDaysOfMonth;
|
||||
private Method parseMonth;
|
||||
private Method parseDaysOfWeek;
|
||||
|
||||
public CronReconciler() {
|
||||
initReflection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reconcile(String text, int startPosition, IProblemCollector problemCollector) {
|
||||
CronLexer lexer = new CronLexer(CharStreams.fromString(text));
|
||||
CommonTokenStream antlrTokens = new CommonTokenStream(lexer);
|
||||
CronParser parser = new CronParser(antlrTokens);
|
||||
AtomicReference<DefaultLineTracker> lineTrackerRef = new AtomicReference<>();
|
||||
|
||||
lexer.removeErrorListener(ConsoleErrorListener.INSTANCE);
|
||||
parser.removeErrorListener(ConsoleErrorListener.INSTANCE);
|
||||
|
||||
parser.addParseListener(new CronParserBaseListener() {
|
||||
|
||||
@Override
|
||||
public void exitSecondsElement(SecondsElementContext ctx) {
|
||||
validate(ctx, parseSeconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitMinutesElement(MinutesElementContext ctx) {
|
||||
validate(ctx, parseMinutes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitHoursElement(HoursElementContext ctx) {
|
||||
validate(ctx, parseHours);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitDaysElement(DaysElementContext ctx) {
|
||||
validate(ctx, parseDaysOfMonth);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitMonthsElement(MonthsElementContext ctx) {
|
||||
validate(ctx, parseMonth);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitDaysOfWeekElement(DaysOfWeekElementContext ctx) {
|
||||
validate(ctx, parseDaysOfWeek);
|
||||
}
|
||||
|
||||
private void validate(ParserRuleContext ctx, Method m) {
|
||||
if (!hasSyntaxErrors(ctx) && m != null) {
|
||||
try {
|
||||
m.invoke(null, ctx.getText());
|
||||
} catch (IllegalAccessException e) {
|
||||
log.error("", e);
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.error("", e);
|
||||
} catch (InvocationTargetException e) {
|
||||
Throwable target = e.getTargetException();
|
||||
String message = target.getMessage();
|
||||
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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void markProblemsForNumberFormatException(ParserRuleContext ctx, String message) {
|
||||
int start = message.indexOf("\"");
|
||||
if (start >= 0) {
|
||||
int end = message.lastIndexOf("\"");
|
||||
if (start + 1 < end) {
|
||||
String text = ctx.getText();
|
||||
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()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
problemCollector.accept(new ReconcileProblemImpl(CronProblemType.FIELD, "CRON: %s".formatted(message), startPosition + ctx.getStart().getStartIndex(), ctx.getText().length()));
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
ANTLRErrorListener antlrErrorListener = new ANTLRErrorListener() {
|
||||
|
||||
@Override
|
||||
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine,
|
||||
String msg, RecognitionException e) {
|
||||
int offset = 0;
|
||||
int length = 1;
|
||||
if (offendingSymbol instanceof Token) {
|
||||
Token token = (Token) offendingSymbol;
|
||||
offset = token.getStartIndex();
|
||||
length = token.getText().length();
|
||||
} else {
|
||||
DefaultLineTracker lt = lineTrackerRef.get();
|
||||
if (lt == null) {
|
||||
lt = new DefaultLineTracker();
|
||||
lt.set(text);
|
||||
lineTrackerRef.set(lt);
|
||||
}
|
||||
try {
|
||||
offset = lt.getLineOffset(line - 1) + charPositionInLine;
|
||||
} catch (BadLocationException e1) {
|
||||
log.error("", e1);
|
||||
}
|
||||
}
|
||||
problemCollector.accept(new ReconcileProblemImpl(CronProblemType.SYNTAX, "CRON: " + msg, startPosition + offset, length));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportContextSensitivity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, int prediction,
|
||||
ATNConfigSet configs) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportAttemptingFullContext(Parser recognizer, DFA dfa, int startIndex, int stopIndex,
|
||||
BitSet conflictingAlts, ATNConfigSet configs) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportAmbiguity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, boolean exact,
|
||||
BitSet ambigAlts, ATNConfigSet configs) {
|
||||
}
|
||||
};
|
||||
|
||||
lexer.addErrorListener(antlrErrorListener);
|
||||
parser.addErrorListener(antlrErrorListener);
|
||||
|
||||
parser.cronExpression();
|
||||
}
|
||||
|
||||
private boolean hasSyntaxErrors(ParserRuleContext ctx) {
|
||||
return ctx.accept(new AbstractParseTreeVisitor<Boolean>() {
|
||||
|
||||
@Override
|
||||
public Boolean visitErrorNode(ErrorNode node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean defaultResult() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldVisitNextChild(RuleNode node, Boolean currentResult) {
|
||||
return currentResult == null || !currentResult.booleanValue();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void initReflection() {
|
||||
try {
|
||||
Class<?> clazz = Class.forName("org.springframework.scheduling.support.CronField");
|
||||
parseSeconds = clazz.getDeclaredMethod("parseSeconds", String.class);
|
||||
parseSeconds.setAccessible(true);
|
||||
parseMinutes = clazz.getDeclaredMethod("parseMinutes", String.class);
|
||||
parseMinutes.setAccessible(true);
|
||||
parseHours = clazz.getDeclaredMethod("parseHours", String.class);
|
||||
parseHours.setAccessible(true);
|
||||
parseDaysOfMonth = clazz.getDeclaredMethod("parseDaysOfMonth", String.class);
|
||||
parseDaysOfMonth.setAccessible(true);
|
||||
parseMonth = clazz.getDeclaredMethod("parseMonth", String.class);
|
||||
parseMonth.setAccessible(true);
|
||||
parseDaysOfWeek = clazz.getDeclaredMethod("parseDaysOfWeek", String.class);
|
||||
parseDaysOfWeek.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
log.error("", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
/*******************************************************************************
|
||||
* 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.cron;
|
||||
|
||||
import static org.springframework.ide.vscode.parser.cron.CronLexer.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.antlr.v4.runtime.ANTLRErrorListener;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.ConsoleErrorListener;
|
||||
import org.antlr.v4.runtime.Parser;
|
||||
import org.antlr.v4.runtime.RecognitionException;
|
||||
import org.antlr.v4.runtime.Recognizer;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
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.commons.languageserver.semantic.tokens.SemanticTokenData;
|
||||
import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokensDataProvider;
|
||||
import org.springframework.ide.vscode.parser.cron.CronLexer;
|
||||
import org.springframework.ide.vscode.parser.cron.CronParser;
|
||||
import org.springframework.ide.vscode.parser.spel.SpelParserBaseListener;
|
||||
|
||||
public class CronSemanticTokens implements SemanticTokensDataProvider {
|
||||
|
||||
private final Optional<Consumer<RecognitionException>> parseErrorHandler;
|
||||
|
||||
public CronSemanticTokens(Optional<Consumer<RecognitionException>> parseErrorHandler) {
|
||||
this.parseErrorHandler = parseErrorHandler;
|
||||
}
|
||||
|
||||
public CronSemanticTokens() {
|
||||
this(Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTokenTypes() {
|
||||
return List.of("operator", "number", "enum", "macro", "method");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SemanticTokenData> computeTokens(String text, int initialOffset) {
|
||||
CronLexer lexer = new CronLexer(CharStreams.fromString(text));
|
||||
CommonTokenStream antlrTokens = new CommonTokenStream(lexer);
|
||||
CronParser parser = new CronParser(antlrTokens);
|
||||
|
||||
Map<Token, String> semantics = new HashMap<>();
|
||||
|
||||
lexer.removeErrorListener(ConsoleErrorListener.INSTANCE);
|
||||
parser.removeErrorListener(ConsoleErrorListener.INSTANCE);
|
||||
|
||||
List<SemanticTokenData> tokens = new ArrayList<>();
|
||||
|
||||
parser.addParseListener(new SpelParserBaseListener() {
|
||||
|
||||
private void processTerminalNode(TerminalNode node) {
|
||||
Token token = node.getSymbol();
|
||||
switch (token.getType()) {
|
||||
case COMMA:
|
||||
case DASH:
|
||||
case QUESTION:
|
||||
case SLASH:
|
||||
case STAR:
|
||||
case TAG:
|
||||
semantics.put(token, "operator");
|
||||
break;
|
||||
case L:
|
||||
case W:
|
||||
case LW:
|
||||
semantics.put(token, "method");
|
||||
break;
|
||||
case MON:
|
||||
case TUE:
|
||||
case WED:
|
||||
case THU:
|
||||
case FRI:
|
||||
case SAT:
|
||||
case SUN:
|
||||
case JAN:
|
||||
case FEB:
|
||||
case MAR:
|
||||
case APR:
|
||||
case MAY:
|
||||
case JUN:
|
||||
case JUL:
|
||||
case AUG:
|
||||
case SEP:
|
||||
case OCT:
|
||||
case NOV:
|
||||
case DEC:
|
||||
case IDENTIFIER:
|
||||
semantics.put(token, "enum");
|
||||
break;
|
||||
case INT:
|
||||
semantics.put(token, "number");
|
||||
break;
|
||||
case MACRO:
|
||||
semantics.put(token, "macro");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTerminal(TerminalNode node) {
|
||||
processTerminalNode(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitErrorNode(ErrorNode node) {
|
||||
processTerminalNode(node);
|
||||
}
|
||||
});
|
||||
|
||||
parser.addErrorListener(new ANTLRErrorListener() {
|
||||
|
||||
@Override
|
||||
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine,
|
||||
String msg, RecognitionException e) {
|
||||
parseErrorHandler.ifPresent(h -> h.accept(e));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportContextSensitivity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, int prediction,
|
||||
ATNConfigSet configs) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportAttemptingFullContext(Parser recognizer, DFA dfa, int startIndex, int stopIndex,
|
||||
BitSet conflictingAlts, ATNConfigSet configs) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportAmbiguity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, boolean exact,
|
||||
BitSet ambigAlts, ATNConfigSet configs) {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
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(),
|
||||
new String[0]))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
Collections.sort(tokens);
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*******************************************************************************
|
||||
* 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.cron;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.MemberValuePair;
|
||||
import org.eclipse.jdt.core.dom.NormalAnnotation;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.data.jpa.queries.QueryJdtAstReconciler;
|
||||
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;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
|
||||
public class JdtCronReconciler implements JdtAstReconciler {
|
||||
|
||||
private final CronReconciler cronReconciler;
|
||||
|
||||
public JdtCronReconciler(CronReconciler cronReconciler) {
|
||||
this.cronReconciler = cronReconciler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IJavaProject project) {
|
||||
return SpringProjectUtil.hasDependencyStartingWith(project, "spring-context", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProblemType getProblemType() {
|
||||
return CronProblemType.SYNTAX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ASTVisitor createVisitor(IJavaProject project, URI docURI, CompilationUnit cu,
|
||||
IProblemCollector problemCollector, boolean isCompleteAst) {
|
||||
return new ASTVisitor() {
|
||||
@Override
|
||||
public boolean visit(NormalAnnotation node) {
|
||||
if (node.getTypeName() != null) {
|
||||
String fqn = node.getTypeName().getFullyQualifiedName();
|
||||
if (JdtCronSemanticTokensProvider.SCHEDULED_SIMPLE_NAME.equals(fqn) || Annotations.SCHEDULED.equals(fqn)) {
|
||||
ITypeBinding typeBinding = node.resolveTypeBinding();
|
||||
if (typeBinding != null && Annotations.SCHEDULED.equals(typeBinding.getQualifiedName())) {
|
||||
for (Object value : node.values()) {
|
||||
if (value instanceof MemberValuePair) {
|
||||
MemberValuePair pair = (MemberValuePair) value;
|
||||
String name = pair.getName().getFullyQualifiedName();
|
||||
if (name != null && "cron".equals(name)) {
|
||||
QueryJdtAstReconciler.reconcileExpression(cronReconciler, pair.getValue(), problemCollector);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.visit(node);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*******************************************************************************
|
||||
* 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.cron;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.MemberValuePair;
|
||||
import org.eclipse.jdt.core.dom.NormalAnnotation;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.JdtSemanticTokensProvider;
|
||||
import org.springframework.ide.vscode.boot.java.data.jpa.queries.JdtDataQuerySemanticTokensProvider;
|
||||
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;
|
||||
import org.springframework.ide.vscode.commons.util.Collector;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
public class JdtCronSemanticTokensProvider implements JdtSemanticTokensProvider {
|
||||
|
||||
final private CronSemanticTokens tokensProvider;
|
||||
|
||||
static final String SCHEDULED_SIMPLE_NAME = "Scheduled";
|
||||
|
||||
|
||||
public JdtCronSemanticTokensProvider(CronSemanticTokens tokensProvider) {
|
||||
this.tokensProvider = tokensProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTokenTypes() {
|
||||
return tokensProvider.getTokenTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTokenModifiers() {
|
||||
return tokensProvider.getTypeModifiers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IJavaProject project) {
|
||||
return SpringProjectUtil.hasDependencyStartingWith(project, "spring-context", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ASTVisitor getTokensComputer(IJavaProject project, TextDocument doc, CompilationUnit cu,
|
||||
Collector<SemanticTokenData> collector) {
|
||||
return new ASTVisitor() {
|
||||
|
||||
@Override
|
||||
public boolean visit(NormalAnnotation node) {
|
||||
if (node.getTypeName() != null) {
|
||||
String fqn = node.getTypeName().getFullyQualifiedName();
|
||||
if (SCHEDULED_SIMPLE_NAME.equals(fqn) || Annotations.SCHEDULED.equals(fqn)) {
|
||||
ITypeBinding typeBinding = node.resolveTypeBinding();
|
||||
if (typeBinding != null && Annotations.SCHEDULED.equals(typeBinding.getQualifiedName())) {
|
||||
for (Object value : node.values()) {
|
||||
if (value instanceof MemberValuePair) {
|
||||
MemberValuePair pair = (MemberValuePair) value;
|
||||
String name = pair.getName().getFullyQualifiedName();
|
||||
if (name != null && "cron".equals(name)) {
|
||||
JdtDataQuerySemanticTokensProvider.computeTokensForExpression(tokensProvider, pair.getValue()).forEach(collector::accept);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.visit(node);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
package org.springframework.ide.vscode.boot.java.data.jpa.queries;
|
||||
|
||||
import java.util.BitSet;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.antlr.v4.runtime.ANTLRErrorListener;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
@@ -31,6 +32,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.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.linetracker.DefaultLineTracker;
|
||||
|
||||
public class AntlrReconciler implements Reconciler {
|
||||
|
||||
@@ -41,6 +44,9 @@ public class AntlrReconciler implements Reconciler {
|
||||
private final Class<? extends Lexer> lexerClass;
|
||||
private final String parseMethod;
|
||||
private final ProblemType problemType;
|
||||
|
||||
// To quickly get around issues with token recognition coming from the Lexer as it might to much to handle in terms of fixing the parser/lexer right away
|
||||
protected boolean errorOnUnrecognizedTokens;
|
||||
|
||||
public AntlrReconciler(String prefix, Class<? extends Parser> parserClass, Class<? extends Lexer> lexerClass,
|
||||
String parseMethod, ProblemType problemType) {
|
||||
@@ -59,19 +65,33 @@ public class AntlrReconciler implements Reconciler {
|
||||
lexer.removeErrorListener(ConsoleErrorListener.INSTANCE);
|
||||
parser.removeErrorListener(ConsoleErrorListener.INSTANCE);
|
||||
|
||||
parser.addErrorListener(new ANTLRErrorListener() {
|
||||
AtomicReference<DefaultLineTracker> lineTrackerRef = new AtomicReference<>();
|
||||
|
||||
ANTLRErrorListener antlrErrorListener = new ANTLRErrorListener() {
|
||||
|
||||
@Override
|
||||
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine,
|
||||
String msg, RecognitionException e) {
|
||||
Token token = (Token) offendingSymbol;
|
||||
int offset = token.getStartIndex();
|
||||
int length = token.getStopIndex() - token.getStartIndex() + 1;
|
||||
if (token.getStartIndex() >= token.getStopIndex()) {
|
||||
offset = token.getStartIndex() - token.getCharPositionInLine();
|
||||
length = token.getCharPositionInLine() + 1;
|
||||
int offset = 0;
|
||||
int length = 1;
|
||||
if (offendingSymbol instanceof Token) {
|
||||
Token token = (Token) offendingSymbol;
|
||||
offset = token.getStartIndex();
|
||||
length = token.getText().length();
|
||||
} else {
|
||||
DefaultLineTracker lt = lineTrackerRef.get();
|
||||
if (lt == null) {
|
||||
lt = new DefaultLineTracker();
|
||||
lt.set(text);
|
||||
lineTrackerRef.set(lt);
|
||||
}
|
||||
try {
|
||||
offset = lt.getLineOffset(line - 1) + charPositionInLine;
|
||||
} catch (BadLocationException e1) {
|
||||
log.error("", e1);
|
||||
}
|
||||
}
|
||||
problemCollector.accept(new ReconcileProblemImpl(problemType, prefix + ": " + msg, startPosition + offset, length));
|
||||
problemCollector.accept(new ReconcileProblemImpl(problemType, String.format("%s: %s", prefix, msg), startPosition + offset, length));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -88,7 +108,12 @@ public class AntlrReconciler implements Reconciler {
|
||||
public void reportAmbiguity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, boolean exact,
|
||||
BitSet ambigAlts, ATNConfigSet configs) {
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (errorOnUnrecognizedTokens) {
|
||||
lexer.addErrorListener(antlrErrorListener);
|
||||
}
|
||||
parser.addErrorListener(antlrErrorListener);
|
||||
|
||||
return parser;
|
||||
}
|
||||
|
||||
@@ -121,9 +121,9 @@ public class JdtDataQuerySemanticTokensProvider implements JdtSemanticTokensProv
|
||||
|
||||
if (queryExpression != null) {
|
||||
if (isNative) {
|
||||
computeTokensForQueryExpression(getSqlSemanticTokensProvider(jp), queryExpression).forEach(tokensData::accept);
|
||||
computeTokensForExpression(getSqlSemanticTokensProvider(jp), queryExpression).forEach(tokensData::accept);
|
||||
} else {
|
||||
computeTokensForQueryExpression(provider, queryExpression).forEach(tokensData::accept);
|
||||
computeTokensForExpression(provider, queryExpression).forEach(tokensData::accept);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ public class JdtDataQuerySemanticTokensProvider implements JdtSemanticTokensProv
|
||||
@Override
|
||||
public boolean visit(SingleMemberAnnotation a) {
|
||||
if (isQueryAnnotation(a)) {
|
||||
computeTokensForQueryExpression(provider, a.getValue()).forEach(tokensData::accept);
|
||||
computeTokensForExpression(provider, a.getValue()).forEach(tokensData::accept);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -144,7 +144,7 @@ public class JdtDataQuerySemanticTokensProvider implements JdtSemanticTokensProv
|
||||
IMethodBinding methodBinding = node.resolveMethodBinding();
|
||||
if ("jakarta.persistence.EntityManager".equals(methodBinding.getDeclaringClass().getQualifiedName())) {
|
||||
if (methodBinding.getParameterTypes().length <= 2 && "java.lang.String".equals(methodBinding.getParameterTypes()[0].getQualifiedName())) {
|
||||
computeTokensForQueryExpression(provider, queryExpr).forEach(tokensData::accept);
|
||||
computeTokensForExpression(provider, queryExpr).forEach(tokensData::accept);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,7 +153,7 @@ public class JdtDataQuerySemanticTokensProvider implements JdtSemanticTokensProv
|
||||
};
|
||||
}
|
||||
|
||||
private static List<SemanticTokenData> computeTokensForQueryExpression(SemanticTokensDataProvider provider, Expression valueExp) {
|
||||
public static List<SemanticTokenData> computeTokensForExpression(SemanticTokensDataProvider provider, Expression valueExp) {
|
||||
String query = null;
|
||||
int offset = 0;
|
||||
if (valueExp instanceof StringLiteral sl) {
|
||||
|
||||
@@ -146,7 +146,7 @@ public class QueryJdtAstReconciler implements JdtAstReconciler {
|
||||
return SpringProjectUtil.hasDependencyStartingWith(project, "hibernate-core", null) ? hqlReconciler : jpqlReconciler;
|
||||
}
|
||||
|
||||
private void reconcileExpression(Reconciler reconciler, Expression valueExp, IProblemCollector problemCollector) {
|
||||
public static void reconcileExpression(Reconciler reconciler, Expression valueExp, IProblemCollector problemCollector) {
|
||||
String query = null;
|
||||
int offset = 0;
|
||||
if (valueExp instanceof StringLiteral sl) {
|
||||
|
||||
@@ -22,6 +22,7 @@ public class SpelReconciler extends AntlrReconciler {
|
||||
|
||||
public SpelReconciler() {
|
||||
super("SPEL", SpelParser.class, SpelLexer.class, "spelExpr", SpelProblemType.JAVA_SPEL_EXPRESSION_SYNTAX);
|
||||
this.errorOnUnrecognizedTokens = false;
|
||||
this.enabled = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -397,7 +397,7 @@
|
||||
},
|
||||
{
|
||||
"id": "data-query",
|
||||
"label": "Data Query",
|
||||
"label": "Data Queries",
|
||||
"toggle": {
|
||||
"label": "Enablement",
|
||||
"values": [
|
||||
@@ -428,5 +428,33 @@
|
||||
"defaultSeverity": "ERROR"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "cron",
|
||||
"label": "CRON Expressions",
|
||||
"toggle": {
|
||||
"label": "Enablement",
|
||||
"values": [
|
||||
"OFF",
|
||||
"ON"
|
||||
],
|
||||
"preferenceKey": "boot-java.validation.cron",
|
||||
"defaultValue": "ON"
|
||||
},
|
||||
"order": 9,
|
||||
"problemTypes": [
|
||||
{
|
||||
"code": "SYNTAX",
|
||||
"label": "Cron Expression Syntax",
|
||||
"description": "Syntax",
|
||||
"defaultSeverity": "ERROR"
|
||||
},
|
||||
{
|
||||
"code": "FIELD",
|
||||
"label": "Cron Expression field",
|
||||
"description": "Field",
|
||||
"defaultSeverity": "ERROR"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,75 @@
|
||||
package org.springframework.ide.vscode.boot.java.cron;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.BasicProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
|
||||
|
||||
public class CronReconcilerTest {
|
||||
|
||||
private CronReconciler reconciler = new CronReconciler();
|
||||
private List<ReconcileProblem> problems;
|
||||
private IProblemCollector collector;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
problems = new ArrayList<>();
|
||||
collector = new BasicProblemCollector(problems);
|
||||
}
|
||||
|
||||
@Test
|
||||
void noProblems_1() {
|
||||
reconciler.reconcile("0 0 0 L-3 * *", 0, collector);
|
||||
assertEquals(0, problems.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void DayOfTheWeekProblems_1() {
|
||||
reconciler.reconcile("0 0 0 8 * MAR-JUL", 0, 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);
|
||||
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);
|
||||
assertEquals(3, problems.size());
|
||||
assertReconcileProblem(problems.get(0), CronProblemType.SYNTAX, 7, 2);
|
||||
assertReconcileProblem(problems.get(1), CronProblemType.SYNTAX, 12, 5);
|
||||
assertReconcileProblem(problems.get(2), CronProblemType.FIELD, 18, 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void syntax_problems_2() {
|
||||
reconciler.reconcile("qq#3 0 Blah 1-88LW * JUL-MARCH", 0, 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);
|
||||
assertEquals(1, problems.size());
|
||||
assertReconcileProblem(problems.get(0), CronProblemType.SYNTAX, 4, 1);
|
||||
}
|
||||
|
||||
static void assertReconcileProblem(ReconcileProblem p, ProblemType type, int offset, int length) {
|
||||
assertEquals(offset, p.getOffset());
|
||||
assertEquals(length, p.getLength());
|
||||
assertEquals(type, p.getType());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
/*******************************************************************************
|
||||
* 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.cron;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokenData;
|
||||
|
||||
public class CronSemanticTokensTest {
|
||||
|
||||
private CronSemanticTokens provider;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
provider = new CronSemanticTokens(Optional.of(Assertions::fail));
|
||||
}
|
||||
|
||||
@Test
|
||||
void topHoueEveryDayEveryWeek() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 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]));
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(4, 5, "operator", new String[0]));
|
||||
assertThat(tokens.get(3)).isEqualTo(new SemanticTokenData(6, 7, "operator", new String[0]));
|
||||
assertThat(tokens.get(4)).isEqualTo(new SemanticTokenData(8, 9, "operator", new String[0]));
|
||||
assertThat(tokens.get(5)).isEqualTo(new SemanticTokenData(10, 11, "operator", new String[0]));
|
||||
}
|
||||
|
||||
@Test
|
||||
void everyTenSeconds() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("*/10 * * * * *", 0);
|
||||
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]));
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(2, 4, "number", new String[0]));
|
||||
assertThat(tokens.get(3)).isEqualTo(new SemanticTokenData(5, 6, "operator", new String[0]));
|
||||
assertThat(tokens.get(4)).isEqualTo(new SemanticTokenData(7, 8, "operator", new String[0]));
|
||||
assertThat(tokens.get(5)).isEqualTo(new SemanticTokenData(9, 10, "operator", new String[0]));
|
||||
assertThat(tokens.get(6)).isEqualTo(new SemanticTokenData(11, 12, "operator", new String[0]));
|
||||
assertThat(tokens.get(7)).isEqualTo(new SemanticTokenData(13, 14, "operator", new String[0]));
|
||||
}
|
||||
|
||||
@Test
|
||||
void betweenEightAndTenEveryDay() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 8-10 * * *", 0);
|
||||
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
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(4, 5, "number", new String[0])); // 8
|
||||
assertThat(tokens.get(3)).isEqualTo(new SemanticTokenData(5, 6, "operator", new String[0])); // -
|
||||
assertThat(tokens.get(4)).isEqualTo(new SemanticTokenData(6, 8, "number", new String[0])); // 10
|
||||
assertThat(tokens.get(5)).isEqualTo(new SemanticTokenData(9, 10, "operator", new String[0])); // *
|
||||
assertThat(tokens.get(6)).isEqualTo(new SemanticTokenData(11, 12, "operator", new String[0])); // *
|
||||
assertThat(tokens.get(7)).isEqualTo(new SemanticTokenData(13, 14, "operator", new String[0])); // *
|
||||
}
|
||||
|
||||
@Test
|
||||
void everyDayBetweenSixAndSeven() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 6,19 * * *", 0);
|
||||
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
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(4, 5, "number", new String[0])); // 6
|
||||
assertThat(tokens.get(3)).isEqualTo(new SemanticTokenData(5, 6, "operator", new String[0])); // ,
|
||||
assertThat(tokens.get(4)).isEqualTo(new SemanticTokenData(6, 8, "number", new String[0])); // 19
|
||||
assertThat(tokens.get(5)).isEqualTo(new SemanticTokenData(9, 10, "operator", new String[0])); // *
|
||||
assertThat(tokens.get(6)).isEqualTo(new SemanticTokenData(11, 12, "operator", new String[0])); // *
|
||||
assertThat(tokens.get(7)).isEqualTo(new SemanticTokenData(13, 14, "operator", new String[0])); // *
|
||||
}
|
||||
|
||||
@Test
|
||||
void everyHalfHourBetweenEightAndEleven() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0/30 8-10 * * *", 0);
|
||||
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
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(3, 4, "operator", new String[0])); // /
|
||||
assertThat(tokens.get(3)).isEqualTo(new SemanticTokenData(4, 6, "number", new String[0])); // 30
|
||||
assertThat(tokens.get(4)).isEqualTo(new SemanticTokenData(7, 8, "number", new String[0])); // 8
|
||||
assertThat(tokens.get(5)).isEqualTo(new SemanticTokenData(8, 9, "operator", new String[0])); // -
|
||||
assertThat(tokens.get(6)).isEqualTo(new SemanticTokenData(9, 11, "number", new String[0])); // 10
|
||||
assertThat(tokens.get(7)).isEqualTo(new SemanticTokenData(12, 13, "operator", new String[0])); // *
|
||||
assertThat(tokens.get(8)).isEqualTo(new SemanticTokenData(14, 15, "operator", new String[0])); // *
|
||||
assertThat(tokens.get(9)).isEqualTo(new SemanticTokenData(16, 17, "operator", new String[0])); // *
|
||||
}
|
||||
|
||||
@Test
|
||||
void nineToFiveOnWeekdays() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 9-17 * * MON-FRI", 0);
|
||||
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
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(4, 5, "number", new String[0])); // 9
|
||||
assertThat(tokens.get(3)).isEqualTo(new SemanticTokenData(5, 6, "operator", new String[0])); // -
|
||||
assertThat(tokens.get(4)).isEqualTo(new SemanticTokenData(6, 8, "number", new String[0])); // 17
|
||||
assertThat(tokens.get(5)).isEqualTo(new SemanticTokenData(9, 10, "operator", new String[0])); // *
|
||||
assertThat(tokens.get(6)).isEqualTo(new SemanticTokenData(11, 12, "operator", new String[0])); // *
|
||||
assertThat(tokens.get(7)).isEqualTo(new SemanticTokenData(13, 16, "enum", new String[0])); // MON
|
||||
assertThat(tokens.get(8)).isEqualTo(new SemanticTokenData(16, 17, "operator", new String[0])); // -
|
||||
assertThat(tokens.get(9)).isEqualTo(new SemanticTokenData(17, 20, "enum", new String[0])); // FRI
|
||||
}
|
||||
|
||||
@Test
|
||||
void christmas() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 25 12 ?", 0);
|
||||
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
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(4, 5, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(3)).isEqualTo(new SemanticTokenData(6, 8, "number", new String[0])); // 25
|
||||
assertThat(tokens.get(4)).isEqualTo(new SemanticTokenData(9, 11, "number", new String[0])); // 12
|
||||
assertThat(tokens.get(5)).isEqualTo(new SemanticTokenData(12, 13, "operator", new String[0])); // ?
|
||||
}
|
||||
|
||||
@Test
|
||||
void lastDayOfMonthAtMidnight() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 L * *", 0);
|
||||
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
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(4, 5, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(3)).isEqualTo(new SemanticTokenData(6, 7, "method", new String[0])); // L
|
||||
assertThat(tokens.get(4)).isEqualTo(new SemanticTokenData(8, 9, "operator", new String[0])); // *
|
||||
assertThat(tokens.get(5)).isEqualTo(new SemanticTokenData(10, 11, "operator", new String[0])); // *
|
||||
}
|
||||
|
||||
@Test
|
||||
void thirdToLasttDayOfMonthAtMidnight() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 L-3 * *", 0);
|
||||
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
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(4, 5, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(3)).isEqualTo(new SemanticTokenData(6, 7, "method", new String[0])); // L
|
||||
assertThat(tokens.get(4)).isEqualTo(new SemanticTokenData(7, 8, "operator", new String[0])); // -
|
||||
assertThat(tokens.get(5)).isEqualTo(new SemanticTokenData(8, 9, "number", new String[0])); // 3
|
||||
assertThat(tokens.get(6)).isEqualTo(new SemanticTokenData(10, 11, "operator", new String[0])); // *
|
||||
assertThat(tokens.get(7)).isEqualTo(new SemanticTokenData(12, 13, "operator", new String[0])); // *
|
||||
}
|
||||
|
||||
@Test
|
||||
void firstWeekDayOfMonthAtMidnight() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 1W * *", 0);
|
||||
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
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(4, 5, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(3)).isEqualTo(new SemanticTokenData(6, 7, "number", new String[0])); // 1
|
||||
assertThat(tokens.get(4)).isEqualTo(new SemanticTokenData(7, 8, "method", new String[0])); // W
|
||||
assertThat(tokens.get(5)).isEqualTo(new SemanticTokenData(9, 10, "operator", new String[0])); // *
|
||||
assertThat(tokens.get(6)).isEqualTo(new SemanticTokenData(11, 12, "operator", new String[0])); // *
|
||||
}
|
||||
|
||||
@Test
|
||||
void lastWeekDayOfMonthAtMidnight() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 LW * *", 0);
|
||||
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
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(4, 5, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(3)).isEqualTo(new SemanticTokenData(6, 8, "method", new String[0])); // LW
|
||||
assertThat(tokens.get(4)).isEqualTo(new SemanticTokenData(9, 10, "operator", new String[0])); // *
|
||||
assertThat(tokens.get(5)).isEqualTo(new SemanticTokenData(11, 12, "operator", new String[0])); // *
|
||||
}
|
||||
|
||||
@Test
|
||||
void lastFridayOfMonthAtMidnight() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 * * 5L", 0);
|
||||
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
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(4, 5, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(3)).isEqualTo(new SemanticTokenData(6, 7, "operator", new String[0])); // *
|
||||
assertThat(tokens.get(4)).isEqualTo(new SemanticTokenData(8, 9, "operator", new String[0])); // *
|
||||
assertThat(tokens.get(5)).isEqualTo(new SemanticTokenData(10, 11, "number", new String[0])); // 5
|
||||
assertThat(tokens.get(6)).isEqualTo(new SemanticTokenData(11, 12, "method", new String[0])); // L
|
||||
}
|
||||
|
||||
@Test
|
||||
void lastThursdayOfMonthAtMidnight() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 * * THUL", 0);
|
||||
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
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(4, 5, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(3)).isEqualTo(new SemanticTokenData(6, 7, "operator", new String[0])); // *
|
||||
assertThat(tokens.get(4)).isEqualTo(new SemanticTokenData(8, 9, "operator", new String[0])); // *
|
||||
assertThat(tokens.get(5)).isEqualTo(new SemanticTokenData(10, 13, "enum", new String[0])); // THU
|
||||
assertThat(tokens.get(6)).isEqualTo(new SemanticTokenData(13, 14, "method", new String[0])); // L
|
||||
}
|
||||
|
||||
@Test
|
||||
void secondFridayOfMonthAtMidnight() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 ? * 5#2", 0);
|
||||
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
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(4, 5, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(3)).isEqualTo(new SemanticTokenData(6, 7, "operator", new String[0])); // ?
|
||||
assertThat(tokens.get(4)).isEqualTo(new SemanticTokenData(8, 9, "operator", new String[0])); // *
|
||||
assertThat(tokens.get(5)).isEqualTo(new SemanticTokenData(10, 11, "number", new String[0])); // 5
|
||||
assertThat(tokens.get(6)).isEqualTo(new SemanticTokenData(11, 12, "operator", new String[0])); // #
|
||||
assertThat(tokens.get(7)).isEqualTo(new SemanticTokenData(12, 13, "number", new String[0])); // 2
|
||||
}
|
||||
|
||||
@Test
|
||||
void firstMondayOfMonthAtMidnight() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 ? * MON#1", 0);
|
||||
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
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(4, 5, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(3)).isEqualTo(new SemanticTokenData(6, 7, "operator", new String[0])); // ?
|
||||
assertThat(tokens.get(4)).isEqualTo(new SemanticTokenData(8, 9, "operator", new String[0])); // *
|
||||
assertThat(tokens.get(5)).isEqualTo(new SemanticTokenData(10, 13, "enum", new String[0])); // MON
|
||||
assertThat(tokens.get(6)).isEqualTo(new SemanticTokenData(13, 14, "operator", new String[0])); // #
|
||||
assertThat(tokens.get(7)).isEqualTo(new SemanticTokenData(14, 15, "number", new String[0])); // 1
|
||||
}
|
||||
|
||||
@Test
|
||||
void macro() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("@yearly", 0);
|
||||
assertThat(tokens.size()).isEqualTo(1);
|
||||
assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 7, "macro", new String[0])); // @yearly
|
||||
}
|
||||
|
||||
@Test
|
||||
void errors_1() {
|
||||
provider = new CronSemanticTokens();
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("0 0 0 8LW * Foo#bar", 0);
|
||||
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
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(4, 5, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(3)).isEqualTo(new SemanticTokenData(6, 7, "number", new String[0])); // 8
|
||||
assertThat(tokens.get(4)).isEqualTo(new SemanticTokenData(7, 9, "method", new String[0])); // LW
|
||||
assertThat(tokens.get(5)).isEqualTo(new SemanticTokenData(10, 11, "operator", new String[0])); // *
|
||||
assertThat(tokens.get(6)).isEqualTo(new SemanticTokenData(12, 15, "enum", new String[0])); // Foo
|
||||
assertThat(tokens.get(7)).isEqualTo(new SemanticTokenData(15, 16, "operator", new String[0])); // #
|
||||
assertThat(tokens.get(8)).isEqualTo(new SemanticTokenData(16, 19, "enum", new String[0])); // bar
|
||||
}
|
||||
|
||||
@Test
|
||||
void errors_2() {
|
||||
provider = new CronSemanticTokens();
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("qq#3 0 Blah 1-88LW * JUL-MARCH", 0);
|
||||
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])); // #
|
||||
assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(3, 4, "number", new String[0])); // 3
|
||||
assertThat(tokens.get(3)).isEqualTo(new SemanticTokenData(5, 6, "number", new String[0])); // 0
|
||||
assertThat(tokens.get(4)).isEqualTo(new SemanticTokenData(7, 11, "enum", new String[0])); // Blah
|
||||
assertThat(tokens.get(5)).isEqualTo(new SemanticTokenData(12, 13, "number", new String[0])); // 1
|
||||
assertThat(tokens.get(6)).isEqualTo(new SemanticTokenData(13, 14, "operator", new String[0])); // -
|
||||
assertThat(tokens.get(7)).isEqualTo(new SemanticTokenData(14, 16, "number", new String[0])); // 88
|
||||
assertThat(tokens.get(8)).isEqualTo(new SemanticTokenData(16, 18, "method", new String[0])); // LW
|
||||
assertThat(tokens.get(9)).isEqualTo(new SemanticTokenData(19, 20, "operator", new String[0])); // *
|
||||
assertThat(tokens.get(10)).isEqualTo(new SemanticTokenData(21, 24, "enum", new String[0])); // JUL
|
||||
assertThat(tokens.get(11)).isEqualTo(new SemanticTokenData(24, 25, "operator", new String[0])); // -
|
||||
assertThat(tokens.get(12)).isEqualTo(new SemanticTokenData(25, 30, "enum", new String[0])); // MARCH
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*******************************************************************************
|
||||
* 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.cron;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.eclipse.lsp4j.TextDocumentIdentifier;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.ide.vscode.boot.bootiful.BootLanguageServerTest;
|
||||
import org.springframework.ide.vscode.boot.bootiful.SymbolProviderTestConf;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.Settings;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.Editor;
|
||||
import org.springframework.ide.vscode.project.harness.BootLanguageServerHarness;
|
||||
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@BootLanguageServerTest
|
||||
@Import(SymbolProviderTestConf.class)
|
||||
public class JdtCronReconcilerTest {
|
||||
|
||||
@Autowired
|
||||
private BootLanguageServerHarness harness;
|
||||
@Autowired
|
||||
private JavaProjectFinder projectFinder;
|
||||
|
||||
private File directory;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws Exception {
|
||||
harness.intialize(null);
|
||||
|
||||
directory = new File(ProjectsHarness.class.getResource("/test-projects/boot-mysql/").toURI());
|
||||
|
||||
String projectDir = directory.toURI().toString();
|
||||
|
||||
// trigger project creation
|
||||
projectFinder.find(new TextDocumentIdentifier(projectDir)).get();
|
||||
|
||||
String changedSettings = """
|
||||
{
|
||||
"boot-java": {
|
||||
"validation": {
|
||||
"cron": "ON"
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
JsonElement settingsAsJson = new Gson().fromJson(changedSettings, JsonElement.class);
|
||||
harness.changeConfiguration(new Settings(settingsAsJson));
|
||||
}
|
||||
|
||||
@Test
|
||||
void noErrors() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
public class A {
|
||||
|
||||
@Scheduled(cron = "0 0 0 L-3 * *")
|
||||
void foo() {}
|
||||
|
||||
}
|
||||
""";
|
||||
String docUri = directory.toPath().resolve("src/main/java/example/demo/A.java").toUri()
|
||||
.toString();
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA, source, docUri);
|
||||
editor.assertProblems();
|
||||
}
|
||||
|
||||
@Test
|
||||
void errorsReported_1() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
public class A {
|
||||
|
||||
@Scheduled(cron = "0 0 0 8LW * MARCH-JUL")
|
||||
void foo() {}
|
||||
|
||||
}
|
||||
""";
|
||||
String docUri = directory.toPath().resolve("src/main/java/example/demo/A.java").toUri()
|
||||
.toString();
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA, source, docUri);
|
||||
editor.assertProblems(
|
||||
"LW|CRON: extraneous input 'LW'",
|
||||
"MARCH|CRON: extraneous input 'MARCH' expecting",
|
||||
"JU|CRON: Number expected"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void errorsReported_2() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
public class A {
|
||||
|
||||
@Scheduled(cron = "10/? * * ? * MON-5")
|
||||
void foo() {}
|
||||
|
||||
}
|
||||
""";
|
||||
String docUri = directory.toPath().resolve("src/main/java/example/demo/A.java").toUri()
|
||||
.toString();
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA, source, docUri);
|
||||
editor.assertProblems(
|
||||
"?|CRON: Number expected"
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,370 @@
|
||||
/*******************************************************************************
|
||||
* 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.cron;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.ide.vscode.boot.bootiful.BootLanguageServerTest;
|
||||
import org.springframework.ide.vscode.boot.bootiful.HoverTestConf;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.CompositeASTVisitor;
|
||||
import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache;
|
||||
import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokenData;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.Collector;
|
||||
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@BootLanguageServerTest
|
||||
@Import(HoverTestConf.class)
|
||||
public class JdtCronSemanticTokensProviderTest {
|
||||
|
||||
@Autowired
|
||||
JdtCronSemanticTokensProvider provider;
|
||||
|
||||
private ProjectsHarness projects = ProjectsHarness.INSTANCE;
|
||||
|
||||
private MavenJavaProject jp;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws Exception {
|
||||
jp = projects.mavenProject("spring-modulith-example-full");
|
||||
}
|
||||
|
||||
private List<SemanticTokenData> computeTokens(CompilationUnit cu) {
|
||||
Collector<SemanticTokenData> collector = new Collector<>();
|
||||
CompositeASTVisitor visitor = new CompositeASTVisitor();
|
||||
visitor.add(provider.getTokensComputer(jp, null, cu, collector));
|
||||
cu.accept(visitor);
|
||||
return collector.get();
|
||||
}
|
||||
|
||||
@Test
|
||||
void secondFridayOfMonthAtMidnight() throws Exception {
|
||||
String source = """
|
||||
package my.package
|
||||
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
public class A {
|
||||
|
||||
@Scheduled(cron="0 0 0 ? * 5#2")
|
||||
void foo() {}
|
||||
|
||||
}
|
||||
""";
|
||||
|
||||
String uri = Paths.get(jp.getLocationUri()).resolve("src/main/resource/my/package/A.java").toUri()
|
||||
.toASCIIString();
|
||||
CompilationUnit cu = CompilationUnitCache.parse2(source.toCharArray(), uri, "A.java", jp);
|
||||
|
||||
assertThat(cu).isNotNull();
|
||||
|
||||
List<SemanticTokenData> tokens = computeTokens(cu);
|
||||
|
||||
assertThat(tokens.size()).isEqualTo(8);
|
||||
|
||||
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");
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(119, 120, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).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");
|
||||
|
||||
token = tokens.get(3);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(123, 124, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("?");
|
||||
|
||||
token = tokens.get(4);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(125, 126, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).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");
|
||||
|
||||
token = tokens.get(6);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(128, 129, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).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");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void lastThursdayOfMonthAtMidnight() throws Exception {
|
||||
String source = """
|
||||
package my.package
|
||||
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
public class A {
|
||||
|
||||
@Scheduled(cron="0 0 0 * * THUL")
|
||||
void foo() {}
|
||||
|
||||
}
|
||||
""";
|
||||
|
||||
String uri = Paths.get(jp.getLocationUri()).resolve("src/main/resource/my/package/A.java").toUri()
|
||||
.toASCIIString();
|
||||
CompilationUnit cu = CompilationUnitCache.parse2(source.toCharArray(), uri, "A.java", jp);
|
||||
|
||||
assertThat(cu).isNotNull();
|
||||
|
||||
List<SemanticTokenData> tokens = computeTokens(cu);
|
||||
|
||||
assertThat(tokens.size()).isEqualTo(7);
|
||||
|
||||
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");
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(119, 120, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).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");
|
||||
|
||||
token = tokens.get(3);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(123, 124, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("*");
|
||||
|
||||
token = tokens.get(4);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(125, 126, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).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");
|
||||
|
||||
token = tokens.get(6);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(130, 131, "method", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("L");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void thirdToLasttDayOfMonthAtMidnight() throws Exception {
|
||||
String source = """
|
||||
package my.package
|
||||
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
public class A {
|
||||
|
||||
@Scheduled(cron="0 0 0 L-3 * *")
|
||||
void foo() {}
|
||||
|
||||
}
|
||||
""";
|
||||
|
||||
String uri = Paths.get(jp.getLocationUri()).resolve("src/main/resource/my/package/A.java").toUri()
|
||||
.toASCIIString();
|
||||
CompilationUnit cu = CompilationUnitCache.parse2(source.toCharArray(), uri, "A.java", jp);
|
||||
|
||||
assertThat(cu).isNotNull();
|
||||
|
||||
List<SemanticTokenData> tokens = computeTokens(cu);
|
||||
|
||||
assertThat(tokens.size()).isEqualTo(8);
|
||||
|
||||
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");
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(119, 120, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).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");
|
||||
|
||||
token = tokens.get(3);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(123, 124, "method", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).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("-");
|
||||
|
||||
token = tokens.get(5);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(125, 126, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).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("*");
|
||||
|
||||
token = tokens.get(7);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(129, 130, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).isEqualTo("*");
|
||||
}
|
||||
|
||||
@Test
|
||||
void errors_1() throws Exception {
|
||||
String source = """
|
||||
package my.package
|
||||
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
public class A {
|
||||
|
||||
@Scheduled(cron="0 0 0 8LW * Foo#bar")
|
||||
void foo() {}
|
||||
|
||||
}
|
||||
""";
|
||||
|
||||
String uri = Paths.get(jp.getLocationUri()).resolve("src/main/resource/my/package/A.java").toUri()
|
||||
.toASCIIString();
|
||||
CompilationUnit cu = CompilationUnitCache.parse2(source.toCharArray(), uri, "A.java", jp);
|
||||
|
||||
assertThat(cu).isNotNull();
|
||||
|
||||
List<SemanticTokenData> tokens = computeTokens(cu);
|
||||
|
||||
assertThat(tokens.size()).isEqualTo(9);
|
||||
|
||||
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");
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(119, 120, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).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");
|
||||
|
||||
token = tokens.get(3);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(123, 124, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).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");
|
||||
|
||||
token = tokens.get(5);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(127, 128, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).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");
|
||||
|
||||
token = tokens.get(7);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(132, 133, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).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");
|
||||
}
|
||||
|
||||
@Test
|
||||
void errors_2() throws Exception {
|
||||
String source = """
|
||||
package my.package
|
||||
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
public class A {
|
||||
|
||||
@Scheduled(cron="qq#3 0 Blah 1-88LW * JUL-MARCH")
|
||||
void foo() {}
|
||||
|
||||
}
|
||||
""";
|
||||
|
||||
String uri = Paths.get(jp.getLocationUri()).resolve("src/main/resource/my/package/A.java").toUri()
|
||||
.toASCIIString();
|
||||
CompilationUnit cu = CompilationUnitCache.parse2(source.toCharArray(), uri, "A.java", jp);
|
||||
|
||||
assertThat(cu).isNotNull();
|
||||
|
||||
List<SemanticTokenData> tokens = computeTokens(cu);
|
||||
|
||||
assertThat(tokens.size()).isEqualTo(13);
|
||||
|
||||
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");
|
||||
|
||||
token = tokens.get(1);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(119, 120, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).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");
|
||||
|
||||
token = tokens.get(3);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(122, 123, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).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");
|
||||
|
||||
token = tokens.get(5);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(129, 130, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).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("-");
|
||||
|
||||
token = tokens.get(7);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(131, 133, "number", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).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");
|
||||
|
||||
token = tokens.get(9);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(136, 137, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).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");
|
||||
|
||||
token = tokens.get(11);
|
||||
assertThat(token).isEqualTo(new SemanticTokenData(141, 142, "operator", new String[0]));
|
||||
assertThat(source.substring(token.start(), token.end())).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");
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,8 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
@@ -24,12 +26,11 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import org.springframework.ide.vscode.boot.java.Boot2JavaProblemType;
|
||||
import org.springframework.ide.vscode.boot.java.Boot3JavaProblemType;
|
||||
import org.springframework.ide.vscode.boot.java.SpelProblemType;
|
||||
import org.springframework.ide.vscode.boot.java.SpringAotJavaProblemType;
|
||||
import org.springframework.ide.vscode.boot.java.cron.CronProblemType;
|
||||
import org.springframework.ide.vscode.boot.java.data.jpa.queries.QueryProblemType;
|
||||
import org.springframework.ide.vscode.boot.properties.reconcile.ApplicationPropertiesProblemType;
|
||||
import org.springframework.ide.vscode.boot.validation.generations.preferences.VersionValidationProblemType;
|
||||
@@ -179,6 +180,7 @@ public class ProblemTypesToJson {
|
||||
writer.collectProblemTypeData(SpringAotJavaProblemType.values());
|
||||
writer.collectProblemTypeData(VersionValidationProblemType.values());
|
||||
writer.collectProblemTypeData(QueryProblemType.values());
|
||||
writer.collectProblemTypeData(CronProblemType.values());
|
||||
|
||||
Collections.sort(writer.problemCategories);
|
||||
|
||||
|
||||
462
vscode-extensions/commons-vscode/package-lock.json
generated
462
vscode-extensions/commons-vscode/package-lock.json
generated
@@ -30,10 +30,13 @@
|
||||
"integrity": "sha512-NjADvQGJRECRkNts2xUALwPj/KJkvCOkwkm+/v9pP6mKhVtMh2wABaeAggae4x7+hBNJH0V0mw60Y0kk/rbSpw=="
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "18.11.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz",
|
||||
"integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==",
|
||||
"dev": true
|
||||
"version": "18.19.45",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.45.tgz",
|
||||
"integrity": "sha512-VZxPKNNhjKmaC1SUYowuXSRSMGyQGmQjvvA1xE4QZ0xce2kLtEhPDS+kqpCPBZYgqblCLQ2DAjSzmgCM5auvhA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/vscode": {
|
||||
"version": "1.75.0",
|
||||
@@ -41,6 +44,21 @@
|
||||
"integrity": "sha512-SAr0PoOhJS6FUq5LjNr8C/StBKALZwDVm3+U4pjF/3iYkt3GioJOPV/oB1Sf1l7lROe4TgrMyL5N1yaEgTWycw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/array-buffer-byte-length": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz",
|
||||
"integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.5",
|
||||
"is-array-buffer": "^3.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/async": {
|
||||
"version": "2.6.4",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
|
||||
@@ -50,9 +68,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/available-typed-arrays": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
|
||||
"integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
|
||||
"integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
|
||||
"dependencies": {
|
||||
"possible-typed-array-names": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
@@ -76,12 +97,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
|
||||
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
|
||||
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.1",
|
||||
"get-intrinsic": "^1.0.2"
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"set-function-length": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
@@ -96,15 +123,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/deep-equal": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.0.tgz",
|
||||
"integrity": "sha512-RdpzE0Hv4lhowpIUKKMJfeH6C1pXdtT1/it80ubgWqwI3qpuxUBpC1S4hnHg+zjnuOoDkzUtUCEEkG+XG5l3Mw==",
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz",
|
||||
"integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"es-get-iterator": "^1.1.2",
|
||||
"get-intrinsic": "^1.1.3",
|
||||
"array-buffer-byte-length": "^1.0.0",
|
||||
"call-bind": "^1.0.5",
|
||||
"es-get-iterator": "^1.1.3",
|
||||
"get-intrinsic": "^1.2.2",
|
||||
"is-arguments": "^1.1.1",
|
||||
"is-array-buffer": "^3.0.1",
|
||||
"is-array-buffer": "^3.0.2",
|
||||
"is-date-object": "^1.0.5",
|
||||
"is-regex": "^1.1.4",
|
||||
"is-shared-array-buffer": "^1.0.2",
|
||||
@@ -112,21 +140,41 @@
|
||||
"object-is": "^1.1.5",
|
||||
"object-keys": "^1.1.1",
|
||||
"object.assign": "^4.1.4",
|
||||
"regexp.prototype.flags": "^1.4.3",
|
||||
"regexp.prototype.flags": "^1.5.1",
|
||||
"side-channel": "^1.0.4",
|
||||
"which-boxed-primitive": "^1.0.2",
|
||||
"which-collection": "^1.0.1",
|
||||
"which-typed-array": "^1.1.9"
|
||||
"which-typed-array": "^1.1.13"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/define-data-property": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
||||
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
|
||||
"dependencies": {
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
"gopd": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/define-properties": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
|
||||
"integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
|
||||
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
|
||||
"dependencies": {
|
||||
"define-data-property": "^1.0.1",
|
||||
"has-property-descriptors": "^1.0.0",
|
||||
"object-keys": "^1.1.1"
|
||||
},
|
||||
@@ -137,6 +185,25 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/es-define-property": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
|
||||
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
|
||||
"dependencies": {
|
||||
"get-intrinsic": "^1.2.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-errors": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-get-iterator": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz",
|
||||
@@ -165,9 +232,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/functions-have-names": {
|
||||
"version": "1.2.3",
|
||||
@@ -178,13 +248,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/get-intrinsic": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz",
|
||||
"integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==",
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.1",
|
||||
"has": "^1.0.3",
|
||||
"has-symbols": "^1.0.3"
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3",
|
||||
"hasown": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
@@ -201,17 +276,6 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/has-bigints": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
|
||||
@@ -221,11 +285,22 @@
|
||||
}
|
||||
},
|
||||
"node_modules/has-property-descriptors": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
|
||||
"integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
||||
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
|
||||
"dependencies": {
|
||||
"get-intrinsic": "^1.1.1"
|
||||
"es-define-property": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-proto": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
|
||||
"integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
@@ -243,11 +318,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/has-tostringtag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
|
||||
"integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||
"dependencies": {
|
||||
"has-symbols": "^1.0.2"
|
||||
"has-symbols": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
@@ -256,13 +331,24 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/internal-slot": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz",
|
||||
"integrity": "sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==",
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||
"dependencies": {
|
||||
"get-intrinsic": "^1.1.3",
|
||||
"has": "^1.0.3",
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/internal-slot": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
|
||||
"integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"hasown": "^2.0.0",
|
||||
"side-channel": "^1.0.4"
|
||||
},
|
||||
"engines": {
|
||||
@@ -285,13 +371,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/is-array-buffer": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz",
|
||||
"integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==",
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
|
||||
"integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"get-intrinsic": "^1.1.3",
|
||||
"is-typed-array": "^1.1.10"
|
||||
"get-intrinsic": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
@@ -349,9 +437,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/is-map": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz",
|
||||
"integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==",
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
|
||||
"integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
@@ -386,19 +477,25 @@
|
||||
}
|
||||
},
|
||||
"node_modules/is-set": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz",
|
||||
"integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==",
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
|
||||
"integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-shared-array-buffer": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
|
||||
"integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz",
|
||||
"integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2"
|
||||
"call-bind": "^1.0.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
@@ -432,17 +529,10 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-typed-array": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz",
|
||||
"integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==",
|
||||
"dependencies": {
|
||||
"available-typed-arrays": "^1.0.5",
|
||||
"call-bind": "^1.0.2",
|
||||
"for-each": "^0.3.3",
|
||||
"gopd": "^1.0.1",
|
||||
"has-tostringtag": "^1.0.0"
|
||||
},
|
||||
"node_modules/is-weakmap": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
|
||||
"integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
@@ -450,21 +540,16 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-weakmap": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz",
|
||||
"integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-weakset": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz",
|
||||
"integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==",
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz",
|
||||
"integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"get-intrinsic": "^1.1.1"
|
||||
"call-bind": "^1.0.7",
|
||||
"get-intrinsic": "^1.2.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
@@ -480,18 +565,6 @@
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
|
||||
@@ -505,9 +578,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/minimist": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
|
||||
"integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==",
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
||||
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
@@ -529,20 +602,23 @@
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
},
|
||||
"node_modules/object-inspect": {
|
||||
"version": "1.12.3",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
|
||||
"integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
|
||||
"version": "1.13.2",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
|
||||
"integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/object-is": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz",
|
||||
"integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==",
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz",
|
||||
"integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"define-properties": "^1.1.3"
|
||||
"call-bind": "^1.0.7",
|
||||
"define-properties": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
@@ -560,12 +636,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/object.assign": {
|
||||
"version": "4.1.4",
|
||||
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
|
||||
"integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
|
||||
"version": "4.1.5",
|
||||
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
|
||||
"integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"define-properties": "^1.1.4",
|
||||
"call-bind": "^1.0.5",
|
||||
"define-properties": "^1.2.1",
|
||||
"has-symbols": "^1.0.3",
|
||||
"object-keys": "^1.1.1"
|
||||
},
|
||||
@@ -589,14 +665,23 @@
|
||||
"node": ">= 0.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/possible-typed-array-names": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
|
||||
"integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/regexp.prototype.flags": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
|
||||
"integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==",
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
|
||||
"integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"define-properties": "^1.1.3",
|
||||
"functions-have-names": "^1.2.2"
|
||||
"call-bind": "^1.0.6",
|
||||
"define-properties": "^1.2.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"set-function-name": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
@@ -606,13 +691,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.3.8",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
|
||||
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
|
||||
"version": "7.6.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
|
||||
"integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
@@ -620,14 +702,48 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/side-channel": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
|
||||
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
|
||||
"node_modules/set-function-length": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.0",
|
||||
"get-intrinsic": "^1.0.2",
|
||||
"object-inspect": "^1.9.0"
|
||||
"define-data-property": "^1.1.4",
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"gopd": "^1.0.1",
|
||||
"has-property-descriptors": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/set-function-name": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
|
||||
"integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
|
||||
"dependencies": {
|
||||
"define-data-property": "^1.1.4",
|
||||
"es-errors": "^1.3.0",
|
||||
"functions-have-names": "^1.2.3",
|
||||
"has-property-descriptors": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/side-channel": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
|
||||
"integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.7",
|
||||
"es-errors": "^1.3.0",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"object-inspect": "^1.13.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
@@ -657,6 +773,12 @@
|
||||
"node": ">=4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/vscode-jsonrpc": {
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz",
|
||||
@@ -712,30 +834,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/which-collection": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz",
|
||||
"integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
|
||||
"integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
|
||||
"dependencies": {
|
||||
"is-map": "^2.0.1",
|
||||
"is-set": "^2.0.1",
|
||||
"is-weakmap": "^2.0.1",
|
||||
"is-weakset": "^2.0.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/which-typed-array": {
|
||||
"version": "1.1.9",
|
||||
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz",
|
||||
"integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==",
|
||||
"dependencies": {
|
||||
"available-typed-arrays": "^1.0.5",
|
||||
"call-bind": "^1.0.2",
|
||||
"for-each": "^0.3.3",
|
||||
"gopd": "^1.0.1",
|
||||
"has-tostringtag": "^1.0.0",
|
||||
"is-typed-array": "^1.1.10"
|
||||
"is-map": "^2.0.3",
|
||||
"is-set": "^2.0.3",
|
||||
"is-weakmap": "^2.0.2",
|
||||
"is-weakset": "^2.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
@@ -744,11 +850,23 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
"node_modules/which-typed-array": {
|
||||
"version": "1.1.15",
|
||||
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz",
|
||||
"integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==",
|
||||
"dependencies": {
|
||||
"available-typed-arrays": "^1.0.7",
|
||||
"call-bind": "^1.0.7",
|
||||
"for-each": "^0.3.3",
|
||||
"gopd": "^1.0.1",
|
||||
"has-tostringtag": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1173,7 +1173,7 @@
|
||||
},
|
||||
{
|
||||
"id": "data-query",
|
||||
"title": "Data Query",
|
||||
"title": "Data Queries",
|
||||
"order": 408,
|
||||
"properties": {
|
||||
"boot-java.validation.data-query": {
|
||||
@@ -1222,6 +1222,46 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "cron",
|
||||
"title": "CRON Expressions",
|
||||
"order": 409,
|
||||
"properties": {
|
||||
"boot-java.validation.cron": {
|
||||
"type": "string",
|
||||
"default": "ON",
|
||||
"description": "Enablement",
|
||||
"enum": [
|
||||
"OFF",
|
||||
"ON"
|
||||
]
|
||||
},
|
||||
"spring-boot.ls.problem.cron.SYNTAX": {
|
||||
"type": "string",
|
||||
"default": "ERROR",
|
||||
"description": "Syntax",
|
||||
"enum": [
|
||||
"IGNORE",
|
||||
"INFO",
|
||||
"WARNING",
|
||||
"HINT",
|
||||
"ERROR"
|
||||
]
|
||||
},
|
||||
"spring-boot.ls.problem.cron.FIELD": {
|
||||
"type": "string",
|
||||
"default": "ERROR",
|
||||
"description": "Field",
|
||||
"enum": [
|
||||
"IGNORE",
|
||||
"INFO",
|
||||
"WARNING",
|
||||
"HINT",
|
||||
"ERROR"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"grammars": [
|
||||
|
||||
Reference in New Issue
Block a user