UNPKG

greybel-languageserver-core

Version:
381 lines 16.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildTokens = exports.TokenHandler = exports.semanticTokensLegend = exports.SemanticTokenModifier = exports.SemanticTokenType = void 0; const greybel_core_1 = require("greybel-core"); const greyscript_core_1 = require("greyscript-core"); const greyscript_meta_1 = require("greyscript-meta"); const miniscript_core_1 = require("miniscript-core"); var SemanticTokenType; (function (SemanticTokenType) { SemanticTokenType[SemanticTokenType["Keyword"] = 0] = "Keyword"; SemanticTokenType[SemanticTokenType["String"] = 1] = "String"; SemanticTokenType[SemanticTokenType["Number"] = 2] = "Number"; SemanticTokenType[SemanticTokenType["Variable"] = 3] = "Variable"; SemanticTokenType[SemanticTokenType["Property"] = 4] = "Property"; SemanticTokenType[SemanticTokenType["Function"] = 5] = "Function"; SemanticTokenType[SemanticTokenType["Parameter"] = 6] = "Parameter"; SemanticTokenType[SemanticTokenType["Operator"] = 7] = "Operator"; SemanticTokenType[SemanticTokenType["Comment"] = 8] = "Comment"; SemanticTokenType[SemanticTokenType["Constant"] = 9] = "Constant"; SemanticTokenType[SemanticTokenType["Punctuator"] = 10] = "Punctuator"; })(SemanticTokenType = exports.SemanticTokenType || (exports.SemanticTokenType = {})); var SemanticTokenModifier; (function (SemanticTokenModifier) { SemanticTokenModifier[SemanticTokenModifier["Declaration"] = 0] = "Declaration"; SemanticTokenModifier[SemanticTokenModifier["Definition"] = 1] = "Definition"; SemanticTokenModifier[SemanticTokenModifier["Readonly"] = 2] = "Readonly"; SemanticTokenModifier[SemanticTokenModifier["Static"] = 3] = "Static"; SemanticTokenModifier[SemanticTokenModifier["Deprecated"] = 4] = "Deprecated"; SemanticTokenModifier[SemanticTokenModifier["Abstract"] = 5] = "Abstract"; SemanticTokenModifier[SemanticTokenModifier["Async"] = 6] = "Async"; SemanticTokenModifier[SemanticTokenModifier["Modification"] = 7] = "Modification"; SemanticTokenModifier[SemanticTokenModifier["Documentation"] = 8] = "Documentation"; SemanticTokenModifier[SemanticTokenModifier["DefaultLibrary"] = 9] = "DefaultLibrary"; })(SemanticTokenModifier = exports.SemanticTokenModifier || (exports.SemanticTokenModifier = {})); exports.semanticTokensLegend = { tokenTypes: [ 'keyword', 'string', 'number', 'variable', 'property', 'function', 'parameter', 'operator', 'comment', 'constant', 'punctuator' ], tokenModifiers: [ 'declaration', 'definition', 'readonly', 'static', 'deprecated', 'abstract', 'async', 'modification', 'documentation', 'defaultLibrary' ] }; const getSingularModifier = (modifier) => { return 1 << modifier; }; class TokenHandler { constructor(lexer, builder) { this._lexer = lexer; this._builder = builder; } next() { this.previousToken = this.token; this.token = this._lexer.next(); } isType(type) { return this.token !== null && type === this.token.type; } consume(selector) { if (selector(this.token)) { this.next(); return true; } return false; } consumeMany(selectorGroup) { if (selectorGroup(this.token)) { this.next(); return true; } return false; } processMultilineToken(token, lines, type) { if (lines.length > 1) { this._builder.push(token.start.line - 1, token.start.character - 1, lines[0].length, type, 0); for (let offset = 1; offset < lines.length; offset++) { this._builder.push(token.start.line + offset - 1, 0, lines[offset].length, type, 0); } } else { this._builder.push(token.start.line - 1, token.start.character - 1, lines[0].length, type, 0); } } processFunction() { const me = this; if (!miniscript_core_1.SelectorGroups.BlockEndOfLine(me.token)) { if (!me.consume(miniscript_core_1.Selectors.LParenthesis)) return; me._builder.push(me.previousToken.start.line - 1, me.previousToken.start.character - 1, me.previousToken.value.length, SemanticTokenType.Punctuator, 0); while (!miniscript_core_1.SelectorGroups.FunctionDeclarationArgEnd(me.token)) { if (me.token.type !== miniscript_core_1.TokenType.Identifier) { return; } me._builder.push(me.token.start.line - 1, me.token.start.character - 1, me.token.value.length, SemanticTokenType.Parameter, 0); me.next(); if (me.consume(miniscript_core_1.Selectors.Assign)) { me._builder.push(me.previousToken.start.line - 1, me.previousToken.start.character - 1, me.previousToken.value.length, SemanticTokenType.Operator, 0); while (!miniscript_core_1.Selectors.ArgumentSeperator(me.token) && !miniscript_core_1.Selectors.RParenthesis(me.token) && !miniscript_core_1.Selectors.EndOfLine(me.token)) { me.process(); } } if (!miniscript_core_1.Selectors.RParenthesis(me.token)) { if (!miniscript_core_1.Selectors.ArgumentSeperator(me.token)) return; me._builder.push(me.token.start.line - 1, me.token.start.character - 1, me.token.value.length, SemanticTokenType.Punctuator, 0); me.next(); } } if (me.consume(miniscript_core_1.Selectors.RParenthesis)) { me._builder.push(me.previousToken.start.line - 1, me.previousToken.start.character - 1, me.previousToken.value.length, SemanticTokenType.Punctuator, 0); } } } processPathSegment() { const me = this; if (this.token.type === miniscript_core_1.ASTType.StringLiteral) { const token = this.token; me._builder.push(token.start.line - 1, token.start.character - 1, token.raw.length, SemanticTokenType.String, 0); this.next(); return; } let path = ''; while (!greybel_core_1.SelectorGroups.PathSegmentEnd(me.token)) { me._builder.push(me.token.start.line - 1, me.token.start.character - 1, me.token.value.length, SemanticTokenType.String, 0); path = path + me.token.value; me.next(); } if (me.consumeMany(greybel_core_1.SelectorGroups.PathSegmentEnd)) { me._builder.push(me.previousToken.start.line - 1, me.previousToken.start.character - 1, me.previousToken.value.length, SemanticTokenType.Punctuator, 0); } return path; } processFeatureEnvarExpression() { const me = this; if (me.token.type !== miniscript_core_1.TokenType.StringLiteral) { return; } me._builder.push(me.token.start.line - 1, me.token.start.character - 1, me.token.value.length, SemanticTokenType.String, 0); me.next(); } processFeatureInjectExpression() { const me = this; me.processPathSegment(); } processFeatureImportStatement() { const me = this; if (me.token.type !== miniscript_core_1.TokenType.Identifier) { return; } me._builder.push(me.token.start.line - 1, me.token.start.character - 1, me.token.value.length, SemanticTokenType.Variable, 0); me.next(); if (!me.consume(greybel_core_1.Selectors.From)) { return; } me._builder.push(me.previousToken.start.line - 1, me.previousToken.start.character - 1, me.previousToken.value.length, SemanticTokenType.Keyword, 0); me.processPathSegment(); } processFeatureIncludeStatement() { const me = this; me.processPathSegment(); } processNativeImportCodeStatement() { const me = this; if (!me.consume(miniscript_core_1.Selectors.LParenthesis)) { return; } me._builder.push(me.previousToken.start.line - 1, me.previousToken.start.character - 1, me.previousToken.value.length, SemanticTokenType.Punctuator, 0); if (miniscript_core_1.TokenType.StringLiteral !== me.token.type) { return; } me._builder.push(me.token.start.line - 1, me.token.start.character - 1, me.token.raw.length, SemanticTokenType.String, 0); me.next(); if (me.consume(miniscript_core_1.Selectors.ImportCodeSeperator)) { me._builder.push(me.previousToken.start.line - 1, me.previousToken.start.character - 1, me.previousToken.value.length, SemanticTokenType.Punctuator, 0); if (!me.isType(miniscript_core_1.TokenType.StringLiteral)) { return; } const token = me.token; me._builder.push(token.start.line - 1, token.start.character - 1, token.raw.length, SemanticTokenType.String, 0); me.next(); } if (!me.consume(miniscript_core_1.Selectors.RParenthesis)) { return; } me._builder.push(me.previousToken.start.line - 1, me.previousToken.start.character - 1, me.previousToken.value.length, SemanticTokenType.Punctuator, 0); } processKeyword() { const token = this.token; this._builder.push(token.start.line - 1, token.start.character - 1, token.value.length, SemanticTokenType.Keyword, 0); this.next(); switch (token.value) { case miniscript_core_1.Keyword.Function: { this.processFunction(); return; } case greybel_core_1.GreybelKeyword.Include: case greybel_core_1.GreybelKeyword.IncludeWithComment: { this.processFeatureIncludeStatement(); return; } case greybel_core_1.GreybelKeyword.Import: case greybel_core_1.GreybelKeyword.ImportWithComment: { this.processFeatureImportStatement(); return; } case greybel_core_1.GreybelKeyword.Envar: { this.processFeatureEnvarExpression(); return; } case greybel_core_1.GreybelKeyword.Inject: { this.processFeatureInjectExpression(); return; } case greybel_core_1.GreybelKeyword.Debugger: { return; } case greyscript_core_1.GreyScriptKeyword.ImportCode: { this.processNativeImportCodeStatement(); } } } processStringLiteral() { const token = this.token; this.processMultilineToken(token, token.raw.split('\n'), SemanticTokenType.String); this.next(); } processNumericLiteral() { const token = this.token; this._builder.push(token.start.line - 1, token.start.character - 1, token.raw.length, SemanticTokenType.Number, 0); this.next(); } processBooleanLiteral() { const token = this.token; this._builder.push(token.start.line - 1, token.start.character - 1, token.raw.length, SemanticTokenType.Constant, 0); this.next(); } processNilLiteral() { const token = this.token; this._builder.push(token.start.line - 1, token.start.character - 1, token.raw.length, SemanticTokenType.Constant, 0); this.next(); } processIdentifier() { const token = this.token; if (miniscript_core_1.Selectors.MemberSeperator(this.previousToken)) { const isNativeIdentifier = (0, greyscript_meta_1.isNative)(['any'], token.value); const modifier = isNativeIdentifier ? getSingularModifier(SemanticTokenModifier.DefaultLibrary) : 0; this._builder.push(token.start.line - 1, token.start.character - 1, token.value.length, SemanticTokenType.Property, modifier); this.next(); return; } const isNativeIdentifier = (0, greyscript_meta_1.isNative)(['general'], token.value); const modifier = isNativeIdentifier ? getSingularModifier(SemanticTokenModifier.DefaultLibrary) : 0; this._builder.push(token.start.line - 1, token.start.character - 1, token.value.length, SemanticTokenType.Variable, modifier); this.next(); } processPunctuator() { const token = this.token; switch (token.value) { case miniscript_core_1.Operator.Plus: case miniscript_core_1.Operator.Asterik: case miniscript_core_1.Operator.Minus: case miniscript_core_1.Operator.Slash: case miniscript_core_1.Operator.Power: case miniscript_core_1.Operator.Modulo: case miniscript_core_1.Operator.LessThan: case miniscript_core_1.Operator.LessThanOrEqual: case miniscript_core_1.Operator.GreaterThan: case miniscript_core_1.Operator.GreaterThanOrEqual: case miniscript_core_1.Operator.Equal: case miniscript_core_1.Operator.NotEqual: case miniscript_core_1.Operator.Assign: case miniscript_core_1.Operator.AddShorthand: case miniscript_core_1.Operator.SubtractShorthand: case miniscript_core_1.Operator.MultiplyShorthand: case miniscript_core_1.Operator.DivideShorthand: case miniscript_core_1.Operator.ModuloShorthand: case miniscript_core_1.Operator.PowerShorthand: case miniscript_core_1.Operator.Reference: { this._builder.push(token.start.line - 1, token.start.character - 1, token.value.length, SemanticTokenType.Operator, 0); break; } default: { this._builder.push(token.start.line - 1, token.start.character - 1, token.value.length, SemanticTokenType.Punctuator, 0); break; } } this.next(); } processComment() { if (this.token.lastLine != null) { this.processMultilineToken(this.token, `/*${this.token.value}*/`.split('\n'), SemanticTokenType.Comment); } else { this.processMultilineToken(this.token, `//${this.token.value}`.split('\n'), SemanticTokenType.Comment); } this.next(); } process() { const me = this; switch (me.token.type) { case miniscript_core_1.TokenType.Keyword: { this.processKeyword(); break; } case miniscript_core_1.TokenType.StringLiteral: { this.processStringLiteral(); break; } case miniscript_core_1.TokenType.Identifier: { this.processIdentifier(); break; } case miniscript_core_1.TokenType.NumericLiteral: { this.processNumericLiteral(); break; } case miniscript_core_1.TokenType.Punctuator: case miniscript_core_1.TokenType.SliceOperator: { this.processPunctuator(); break; } case miniscript_core_1.TokenType.BooleanLiteral: { this.processBooleanLiteral(); break; } case miniscript_core_1.TokenType.NilLiteral: { this.processNilLiteral(); break; } case miniscript_core_1.TokenType.Comment: { this.processComment(); break; } default: { me.next(); } } } digest() { const me = this; me.next(); while (!miniscript_core_1.Selectors.EndOfFile(me.token)) { me.process(); } } } exports.TokenHandler = TokenHandler; function buildTokens(builder, document) { const lexer = new greyscript_core_1.Lexer(document.textDocument.getText(), { unsafe: true }); const handler = new TokenHandler(lexer, builder); handler.digest(); return builder; } exports.buildTokens = buildTokens; //# sourceMappingURL=semantic-token-builder.js.map