[Monaco] Fix painless lexer to handle divisions and regular expressions correctly (#135423)

This commit is contained in:
Michael Dokolin 2022-06-30 18:08:46 +02:00 committed by GitHub
parent ed07efd794
commit 83757e80fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 10 additions and 19 deletions

View file

@ -120,5 +120,3 @@ npm run build:antlr4ts
```
*Note:* This script should only need to be run if a change has been made to `painless_lexer.g4` or `painless_parser.g4`.
*Note:* There is a manual change made to the `sempred()` method in the generated `painless_lexer.ts`. This needs further investigation, but it appears there is an offset between the rule index and the token value. Without this manual change, ANTLR incorrectly reports an error when using a `/` or regex in a script. There is a comment in the generated code to this effect.

View file

@ -185,14 +185,10 @@ export class painless_lexer extends Lexer {
// @Override
public sempred(_localctx: RuleContext, ruleIndex: number, predIndex: number): boolean {
switch (ruleIndex) {
// DO NOT CHANGE
// This is a manual fix to handle slashes appropriately, DIV: 32
case 32:
case 31:
return this.DIV_sempred(_localctx, predIndex);
// DO NOT CHANGE
// This is a manual fix to handle regexes appropriately, REGEX: 78
case 78:
case 77:
return this.REGEX_sempred(_localctx, predIndex);
}
return true;

View file

@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
import { CharStream } from 'antlr4ts';
import type { Token } from 'antlr4ts';
import { painless_lexer as PainlessLexer } from '../../antlr/painless_lexer';
/*
@ -15,19 +15,16 @@ import { painless_lexer as PainlessLexer } from '../../antlr/painless_lexer';
* Based on the Java implementation: https://github.com/elastic/elasticsearch/blob/feab123ba400b150f3dcd04dd27cf57474b70d5a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/EnhancedPainlessLexer.java#L73
*/
export class PainlessLexerEnhanced extends PainlessLexer {
constructor(input: CharStream) {
super(input);
private lastToken?: Token;
nextToken(): Token {
this.lastToken = super.nextToken();
return this.lastToken;
}
isSlashRegex(): boolean {
const lastToken = super.nextToken();
if (lastToken == null) {
return true;
}
// @ts-ignore
switch (lastToken._type) {
switch (this.lastToken?.type) {
case PainlessLexer.RBRACE:
case PainlessLexer.RP:
case PainlessLexer.OCTAL: