161 lines
3.8 KiB
TypeScript
161 lines
3.8 KiB
TypeScript
import { monacoTypes } from '@grafana/ui';
|
|
|
|
import { TokenTypes } from './types';
|
|
|
|
export class LinkedToken {
|
|
constructor(
|
|
public type: string,
|
|
public value: string,
|
|
public range: monacoTypes.IRange,
|
|
public previous: LinkedToken | null,
|
|
public next: LinkedToken | null,
|
|
public tokenTypes: TokenTypes
|
|
) {}
|
|
|
|
isKeyword(): boolean {
|
|
return this.type === this.tokenTypes.Keyword;
|
|
}
|
|
|
|
isWhiteSpace(): boolean {
|
|
return this.type === this.tokenTypes.Whitespace;
|
|
}
|
|
|
|
isParenthesis(): boolean {
|
|
return this.type === this.tokenTypes.Parenthesis;
|
|
}
|
|
|
|
isIdentifier(): boolean {
|
|
return this.type === this.tokenTypes.Identifier;
|
|
}
|
|
|
|
isString(): boolean {
|
|
return this.type === this.tokenTypes.String;
|
|
}
|
|
|
|
isDoubleQuotedString(): boolean {
|
|
return this.type === this.tokenTypes.Type;
|
|
}
|
|
|
|
isVariable(): boolean {
|
|
return this.type === this.tokenTypes.Variable;
|
|
}
|
|
|
|
isFunction(): boolean {
|
|
return this.type === this.tokenTypes.Function;
|
|
}
|
|
|
|
isNumber(): boolean {
|
|
return this.type === this.tokenTypes.Number;
|
|
}
|
|
|
|
is(type: string, value?: string | number | boolean): boolean {
|
|
const isType = this.type === type;
|
|
return value !== undefined ? isType && this.value === value : isType;
|
|
}
|
|
|
|
endsWith(value: string | number | boolean): boolean {
|
|
return this.value === value || this.value[this.value.length - 1] === value;
|
|
}
|
|
|
|
getPreviousNonWhiteSpaceToken(): LinkedToken | null {
|
|
let curr = this.previous;
|
|
while (curr != null) {
|
|
if (!curr.isWhiteSpace()) {
|
|
return curr;
|
|
}
|
|
curr = curr.previous;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
getPreviousOfType(type: string, value?: string): LinkedToken | null {
|
|
let curr = this.previous;
|
|
while (curr != null) {
|
|
const isType = curr.type === type;
|
|
if (value !== undefined ? isType && curr.value === value : isType) {
|
|
return curr;
|
|
}
|
|
curr = curr.previous;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
getPreviousUntil(type: string, ignoreTypes: string[], value?: string): LinkedToken[] | null {
|
|
let tokens: LinkedToken[] = [];
|
|
let curr = this.previous;
|
|
while (curr != null) {
|
|
if (ignoreTypes.some((t) => t === curr?.type)) {
|
|
curr = curr.previous;
|
|
continue;
|
|
}
|
|
|
|
const isType = curr.type === type;
|
|
if (value !== undefined ? isType && curr.value === value : isType) {
|
|
return tokens;
|
|
}
|
|
if (!curr.isWhiteSpace()) {
|
|
tokens.push(curr);
|
|
}
|
|
curr = curr.previous;
|
|
}
|
|
|
|
return tokens;
|
|
}
|
|
|
|
getNextUntil(type: string, ignoreTypes: string[], value?: string): LinkedToken[] | null {
|
|
let tokens: LinkedToken[] = [];
|
|
let curr = this.next;
|
|
while (curr != null) {
|
|
if (ignoreTypes.some((t) => t === curr?.type)) {
|
|
curr = curr.next;
|
|
continue;
|
|
}
|
|
|
|
const isType = curr.type === type;
|
|
if (value !== undefined ? isType && curr.value === value : isType) {
|
|
return tokens;
|
|
}
|
|
if (!curr.isWhiteSpace()) {
|
|
tokens.push(curr);
|
|
}
|
|
curr = curr.next;
|
|
}
|
|
|
|
return tokens;
|
|
}
|
|
|
|
getPreviousKeyword(): LinkedToken | null {
|
|
let curr = this.previous;
|
|
while (curr != null) {
|
|
if (curr.isKeyword()) {
|
|
return curr;
|
|
}
|
|
curr = curr.previous;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
getNextNonWhiteSpaceToken(): LinkedToken | null {
|
|
let curr = this.next;
|
|
while (curr != null) {
|
|
if (!curr.isWhiteSpace()) {
|
|
return curr;
|
|
}
|
|
curr = curr.next;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
getNextOfType(type: string, value?: string): LinkedToken | null {
|
|
let curr = this.next;
|
|
while (curr != null) {
|
|
const isType = curr.type === type;
|
|
if (value !== undefined ? isType && curr.value === value : isType) {
|
|
return curr;
|
|
}
|
|
curr = curr.next;
|
|
}
|
|
return null;
|
|
}
|
|
}
|