@kusto/monaco-kusto
Version:
CSL, KQL plugin for the Monaco Editor
864 lines • 94.7 kB
JavaScript
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
var _a;
import XRegExp from 'xregexp';
import * as ls from 'vscode-languageserver-types';
import * as s from './schema';
// Replaced with @kusto/language-server imports at build time
import 'language-service';
var k = Kusto.Data.IntelliSense;
var parsing = Kusto.Language.Parsing;
var k2 = Kusto.Language.Editor;
var sym = Kusto.Language.Symbols;
var GlobalState = Kusto.Language.GlobalState;
import { getCslTypeNameFromClrType, getEntityDataTypeFromCslType } from './schema';
var List = System.Collections.Generic.List$1;
function assertNever(x) {
throw new Error('Unexpected object: ' + x);
}
var ParseProperties = /** @class */ (function () {
function ParseProperties(version, uri, rulesProvider, parseMode) {
this.version = version;
this.uri = uri;
this.rulesProvider = rulesProvider;
this.parseMode = parseMode;
}
ParseProperties.prototype.isParseNeeded = function (document, rulesProvider, parseMode) {
if (document.uri === this.uri &&
(!rulesProvider || rulesProvider === this.rulesProvider) &&
document.version <= this.version &&
parseMode &&
parseMode <= this.parseMode) {
return false;
}
return true;
};
return ParseProperties;
}());
export var TokenKind;
(function (TokenKind) {
TokenKind[TokenKind["TableToken"] = 2] = "TableToken";
TokenKind[TokenKind["TableColumnToken"] = 4] = "TableColumnToken";
TokenKind[TokenKind["OperatorToken"] = 8] = "OperatorToken";
TokenKind[TokenKind["SubOperatorToken"] = 16] = "SubOperatorToken";
TokenKind[TokenKind["CalculatedColumnToken"] = 32] = "CalculatedColumnToken";
TokenKind[TokenKind["StringLiteralToken"] = 64] = "StringLiteralToken";
TokenKind[TokenKind["FunctionNameToken"] = 128] = "FunctionNameToken";
TokenKind[TokenKind["UnknownToken"] = 256] = "UnknownToken";
TokenKind[TokenKind["CommentToken"] = 512] = "CommentToken";
TokenKind[TokenKind["PlainTextToken"] = 1024] = "PlainTextToken";
TokenKind[TokenKind["DataTypeToken"] = 2048] = "DataTypeToken";
TokenKind[TokenKind["ControlCommandToken"] = 4096] = "ControlCommandToken";
TokenKind[TokenKind["CommandPartToken"] = 8192] = "CommandPartToken";
TokenKind[TokenKind["QueryParametersToken"] = 16384] = "QueryParametersToken";
TokenKind[TokenKind["CslCommandToken"] = 32768] = "CslCommandToken";
TokenKind[TokenKind["LetVariablesToken"] = 65536] = "LetVariablesToken";
TokenKind[TokenKind["PluginToken"] = 131072] = "PluginToken";
TokenKind[TokenKind["BracketRangeToken"] = 262144] = "BracketRangeToken";
TokenKind[TokenKind["ClientDirectiveToken"] = 524288] = "ClientDirectiveToken";
})(TokenKind || (TokenKind = {}));
var symbolKindToName = (_a = {},
_a[sym.SymbolKind.Cluster] = 'Cluster',
_a[sym.SymbolKind.Column] = 'Column',
_a[sym.SymbolKind.Command] = 'Command',
_a[sym.SymbolKind.Database] = 'Database',
_a[sym.SymbolKind.EntityGroup] = 'EntityGroup',
_a[sym.SymbolKind.EntityGroupElement] = 'EntityGroupElement',
_a[sym.SymbolKind.Error] = 'Error',
_a[sym.SymbolKind.Function] = 'Function',
_a[sym.SymbolKind.Graph] = 'Graph',
_a[sym.SymbolKind.Group] = 'Group',
_a[sym.SymbolKind.MaterializedView] = 'MaterializedView',
_a[sym.SymbolKind.None] = 'None',
_a[sym.SymbolKind.Operator] = 'Operator',
_a[sym.SymbolKind.Option] = 'Option',
_a[sym.SymbolKind.Parameter] = 'Parameter',
_a[sym.SymbolKind.Pattern] = 'Pattern',
_a[sym.SymbolKind.QueryOperatorParameter] = 'QueryOperatorParameter',
_a[sym.SymbolKind.Primitive] = 'Primitive',
_a[sym.SymbolKind.Table] = 'Table',
_a[sym.SymbolKind.Tuple] = 'Tuple',
_a[sym.SymbolKind.Variable] = 'Variable',
_a[sym.SymbolKind.Void] = 'Void',
_a);
/**
* Kusto Language service translates the kusto object model (transpiled from C# by Bridge.Net)
* to the vscode language server types, which are used by vscode language extensions.
* This should make things easier in the future to provide a vscode extension based on this translation layer.
*
* Further translations, if needed, to support specific editors (Atom, sublime, Etc)
* should be done on top of this API, since it is (at least meant to be) a standard that is supported by multiple editors.
*
* Note1: Currently monaco isn't using this object model so further translation will be necessary on calling modules.
*
* Note2: This file is responsible for interacting with the kusto object model and exposing Microsoft language service types.
* An exception to that rule is tokenization (and syntax highlighting which depends on it) -
* since it's not currently part of the Microsoft language service protocol. Thus tokenize() _does_ 'leak' kusto types to the callers.
*/
var KustoLanguageService = /** @class */ (function () {
function KustoLanguageService(schema, languageSettings) {
var _a, _b, _c, _d;
/**
* Taken from:
* https://msazure.visualstudio.com/One/_git/Azure-Kusto-Service?path=/Src/Tools/Kusto.Explorer.Control/QueryEditors/KustoScriptEditor/KustoScriptEditorControl2.xaml.cs&version=GBdev&line=2075&lineEnd=2075&lineStartColumn=9&lineEndColumn=77&lineStyle=plain&_a=contents
*/
this._toOptionKind = (_a = {},
_a[k2.CompletionKind.AggregateFunction] = k.OptionKind.FunctionAggregation,
_a[k2.CompletionKind.BuiltInFunction] = k.OptionKind.FunctionScalar,
_a[k2.CompletionKind.Cluster] = k.OptionKind.Database,
_a[k2.CompletionKind.Column] = k.OptionKind.Column,
_a[k2.CompletionKind.CommandPrefix] = k.OptionKind.Command,
_a[k2.CompletionKind.Database] = k.OptionKind.Database,
_a[k2.CompletionKind.DatabaseFunction] = k.OptionKind.FunctionServerSide,
_a[k2.CompletionKind.Example] = k.OptionKind.Literal,
_a[k2.CompletionKind.Identifier] = k.OptionKind.None,
_a[k2.CompletionKind.Keyword] = k.OptionKind.Option,
_a[k2.CompletionKind.LocalFunction] = k.OptionKind.FunctionLocal,
_a[k2.CompletionKind.MaterialiedView] = k.OptionKind.MaterializedView,
_a[k2.CompletionKind.Parameter] = k.OptionKind.Parameter,
_a[k2.CompletionKind.Punctuation] = k.OptionKind.None,
_a[k2.CompletionKind.QueryPrefix] = k.OptionKind.Operator,
_a[k2.CompletionKind.RenderChart] = k.OptionKind.OptionRender,
_a[k2.CompletionKind.ScalarInfix] = k.OptionKind.None,
_a[k2.CompletionKind.ScalarPrefix] = k.OptionKind.Literal,
_a[k2.CompletionKind.ScalarType] = k.OptionKind.DataType,
_a[k2.CompletionKind.Syntax] = k.OptionKind.None,
_a[k2.CompletionKind.Table] = k.OptionKind.Table,
_a[k2.CompletionKind.TabularPrefix] = k.OptionKind.None,
_a[k2.CompletionKind.TabularSuffix] = k.OptionKind.None,
_a[k2.CompletionKind.Unknown] = k.OptionKind.None,
_a[k2.CompletionKind.Variable] = k.OptionKind.Parameter,
_a[k2.CompletionKind.Option] = k.OptionKind.Option,
_a[k2.CompletionKind.Graph] = k.OptionKind.Graph,
_a[k2.CompletionKind.EntityGroup] = k.OptionKind.EntityGroup,
_a[k2.CompletionKind.StoredQueryResult] = k.OptionKind.StoredQueryResult,
_a);
this.disabledCompletionItemsV2 = {
// render charts
ladderchart: k2.CompletionKind.RenderChart,
pivotchart: k2.CompletionKind.RenderChart,
timeline: k2.CompletionKind.RenderChart,
timepivot: k2.CompletionKind.RenderChart,
'3Dchart': k2.CompletionKind.RenderChart,
list: k2.CompletionKind.RenderChart,
};
this._kustoKindtolsKind = (_b = {},
_b[k.OptionKind.None] = ls.CompletionItemKind.Interface,
_b[k.OptionKind.Operator] = ls.CompletionItemKind.Method,
_b[k.OptionKind.Command] = ls.CompletionItemKind.Method,
_b[k.OptionKind.Service] = ls.CompletionItemKind.Class,
_b[k.OptionKind.Policy] = ls.CompletionItemKind.Reference,
_b[k.OptionKind.Database] = ls.CompletionItemKind.Class,
_b[k.OptionKind.Table] = ls.CompletionItemKind.Class,
_b[k.OptionKind.DataType] = ls.CompletionItemKind.Class,
_b[k.OptionKind.Literal] = ls.CompletionItemKind.Property,
_b[k.OptionKind.Parameter] = ls.CompletionItemKind.Variable,
_b[k.OptionKind.IngestionMapping] = ls.CompletionItemKind.Variable,
_b[k.OptionKind.ExpressionFunction] = ls.CompletionItemKind.Variable,
_b[k.OptionKind.Option] = ls.CompletionItemKind.Interface,
_b[k.OptionKind.OptionKind] = ls.CompletionItemKind.Interface,
_b[k.OptionKind.OptionRender] = ls.CompletionItemKind.Interface,
_b[k.OptionKind.Column] = ls.CompletionItemKind.Function,
_b[k.OptionKind.ColumnString] = ls.CompletionItemKind.Field,
_b[k.OptionKind.ColumnNumeric] = ls.CompletionItemKind.Field,
_b[k.OptionKind.ColumnDateTime] = ls.CompletionItemKind.Field,
_b[k.OptionKind.ColumnTimespan] = ls.CompletionItemKind.Field,
_b[k.OptionKind.FunctionServerSide] = ls.CompletionItemKind.Field,
_b[k.OptionKind.FunctionAggregation] = ls.CompletionItemKind.Field,
_b[k.OptionKind.FunctionFilter] = ls.CompletionItemKind.Field,
_b[k.OptionKind.FunctionScalar] = ls.CompletionItemKind.Field,
_b[k.OptionKind.ClientDirective] = ls.CompletionItemKind.Enum,
_b);
this._kustoKindToLsKindV2 = (_c = {},
_c[k2.CompletionKind.AggregateFunction] = ls.CompletionItemKind.Field,
_c[k2.CompletionKind.BuiltInFunction] = ls.CompletionItemKind.Field,
_c[k2.CompletionKind.Cluster] = ls.CompletionItemKind.Class,
_c[k2.CompletionKind.Column] = ls.CompletionItemKind.Function,
_c[k2.CompletionKind.CommandPrefix] = ls.CompletionItemKind.Field,
_c[k2.CompletionKind.Database] = ls.CompletionItemKind.Class,
_c[k2.CompletionKind.DatabaseFunction] = ls.CompletionItemKind.Field,
_c[k2.CompletionKind.Example] = ls.CompletionItemKind.Text,
_c[k2.CompletionKind.Identifier] = ls.CompletionItemKind.Method,
_c[k2.CompletionKind.Keyword] = ls.CompletionItemKind.Method,
_c[k2.CompletionKind.LocalFunction] = ls.CompletionItemKind.Field,
_c[k2.CompletionKind.MaterialiedView] = ls.CompletionItemKind.Class,
_c[k2.CompletionKind.Parameter] = ls.CompletionItemKind.Variable,
_c[k2.CompletionKind.Punctuation] = ls.CompletionItemKind.Interface,
_c[k2.CompletionKind.QueryPrefix] = ls.CompletionItemKind.Function,
_c[k2.CompletionKind.RenderChart] = ls.CompletionItemKind.Method,
_c[k2.CompletionKind.ScalarInfix] = ls.CompletionItemKind.Field,
_c[k2.CompletionKind.ScalarPrefix] = ls.CompletionItemKind.Field,
_c[k2.CompletionKind.ScalarType] = ls.CompletionItemKind.TypeParameter,
_c[k2.CompletionKind.Syntax] = ls.CompletionItemKind.Method,
_c[k2.CompletionKind.Table] = ls.CompletionItemKind.Class,
_c[k2.CompletionKind.TabularPrefix] = ls.CompletionItemKind.Field,
// datatable, externaldata
_c[k2.CompletionKind.TabularSuffix] = ls.CompletionItemKind.Field,
_c[k2.CompletionKind.Unknown] = ls.CompletionItemKind.Interface,
_c[k2.CompletionKind.Variable] = ls.CompletionItemKind.Variable,
_c[k2.CompletionKind.Option] = ls.CompletionItemKind.Text,
_c[k2.CompletionKind.Graph] = ls.CompletionItemKind.Class,
_c[k2.CompletionKind.EntityGroup] = ls.CompletionItemKind.Class,
_c[k2.CompletionKind.StoredQueryResult] = ls.CompletionItemKind.Field,
_c);
this._tokenKindToClassificationKind = (_d = {},
_d[TokenKind.TableToken] = k2.ClassificationKind.Table,
_d[TokenKind.TableColumnToken] = k2.ClassificationKind.Column,
_d[TokenKind.OperatorToken] = k2.ClassificationKind.QueryOperator,
_d[TokenKind.SubOperatorToken] = k2.ClassificationKind.Function,
_d[TokenKind.CalculatedColumnToken] = k2.ClassificationKind.Column,
_d[TokenKind.StringLiteralToken] = k2.ClassificationKind.Literal,
_d[TokenKind.FunctionNameToken] = k2.ClassificationKind.Function,
_d[TokenKind.UnknownToken] = k2.ClassificationKind.PlainText,
_d[TokenKind.CommentToken] = k2.ClassificationKind.Comment,
_d[TokenKind.PlainTextToken] = k2.ClassificationKind.PlainText,
_d[TokenKind.DataTypeToken] = k2.ClassificationKind.Type,
_d[TokenKind.ControlCommandToken] = k2.ClassificationKind.PlainText, // TODO ?
_d[TokenKind.CommandPartToken] = k2.ClassificationKind.PlainText, // TODO ?
_d[TokenKind.QueryParametersToken] = k2.ClassificationKind.QueryParameter,
_d[TokenKind.CslCommandToken] = k2.ClassificationKind.Keyword, // TODO ?
_d[TokenKind.LetVariablesToken] = k2.ClassificationKind.Identifier, // TODO ?
_d[TokenKind.PluginToken] = k2.ClassificationKind.Function,
_d[TokenKind.BracketRangeToken] = k2.ClassificationKind.Keyword, // TODO ?
_d[TokenKind.ClientDirectiveToken] = k2.ClassificationKind.Keyword,
_d);
this._schemaCache = {};
this._kustoJsSchema = KustoLanguageService.convertToKustoJsSchema(schema);
this.__kustoJsSchemaV2 = this.convertToKustoJsSchemaV2(schema);
this._schema = schema;
this._clustersSetInGlobalState = new Set();
this._nonEmptyDatabaseSetInGlobalState = new Set(); // used to remove clusters that are already in the global state
this.configure(languageSettings);
this._newlineAppendPipePolicy = new Kusto.Data.IntelliSense.ApplyPolicy();
this._newlineAppendPipePolicy.Text = '\n| ';
}
KustoLanguageService.prototype.createDatabaseUniqueName = function (clusterName, databaseName) {
return "".concat(clusterName, "_").concat(databaseName);
};
Object.defineProperty(KustoLanguageService.prototype, "_kustoJsSchemaV2", {
/**
* A getter for __kustoJsSchemaV2
*/
get: function () {
return this.__kustoJsSchemaV2;
},
/**
* A setter for _kustoJsSchemaV2. After a schema (global state) is set, create 2 sets of cluster and database names.
*/
set: function (globalState) {
this.__kustoJsSchemaV2 = globalState;
this._clustersSetInGlobalState.clear();
this._nonEmptyDatabaseSetInGlobalState.clear();
// create 2 Sets with cluster names and database names based on the updated Global State.
for (var i = 0; i < globalState.Clusters.Count; i++) {
var clusterSymbol = this._kustoJsSchemaV2.Clusters.getItem(i);
this._clustersSetInGlobalState.add(clusterSymbol.Name);
for (var i2 = 0; i2 < clusterSymbol.Databases.Count; i2++) {
var databaseSymbol = clusterSymbol.Databases.getItem(i2);
if (databaseSymbol.Tables.Count > 0) {
// only include database with tables
this._nonEmptyDatabaseSetInGlobalState.add(this.createDatabaseUniqueName(clusterSymbol.Name, databaseSymbol.Name));
}
}
}
},
enumerable: false,
configurable: true
});
KustoLanguageService.prototype.configure = function (languageSettings) {
this._languageSettings = languageSettings;
var includeExtendedSyntax = this._languageSettings.completionOptions.includeExtendedSyntax;
this._completionOptions =
Kusto.Language.Editor.CompletionOptions.Default.WithIncludeExtendedSyntax(includeExtendedSyntax).WithIncludePunctuationOnlySyntax(false);
// Since we're still reverting to V1 intellisense for control commands, we need to update the rules provider
// (which is a notion of V1 intellisense).
this.createRulesProvider(this._kustoJsSchema, this._schema.clusterType);
};
KustoLanguageService.prototype.doComplete = function (document, position) {
return this.doCompleteV2(document, position);
};
/**
* important: Only use during development to test Global State.
* Prints clusters, databases and tables that are currently in the GlobalState.
*/
KustoLanguageService.prototype.debugGlobalState = function (globals) {
// iterate over clusters
console.log("globals.Clusters.Count: ".concat(globals.Clusters.Count));
for (var i = 0; i < globals.Clusters.Count; i++) {
var cluster = globals.Clusters.getItem(i);
console.log("cluster: ".concat(cluster.Name));
// iterate over databases
console.log("cluster.Databases.Count: ".concat(cluster.Databases.Count));
for (var i2 = 0; i2 < cluster.Databases.Count; i2++) {
var database = cluster.Databases.getItem(i2);
console.log("cluster.database: [".concat(cluster.Name, "].[").concat(database.Name, "]"));
// iterate over tables
console.log("cluster.Databases.Tables.Count: ".concat(database.Tables.Count));
for (var i3 = 0; i3 < database.Tables.Count; i3++) {
var table = database.Tables.getItem(i3);
console.log("cluster.database.table: [".concat(cluster.Name, "].[").concat(database.Name, "].[").concat(table.Name, "]"));
}
}
}
};
/**
* Prepending the doc of the actual topic at the top
*/
KustoLanguageService.prototype.formatHelpTopic = function (helpTopic) {
return "**".concat(helpTopic.Name, " [(view online)](").concat(helpTopic.Url, ")**\n\n").concat(helpTopic.LongDescription);
};
KustoLanguageService.prototype.doCompleteV2 = function (document, position) {
var _this = this;
if (!document) {
return Promise.resolve(ls.CompletionList.create([]));
}
var script = this.parseDocumentV2(document);
// print cluster/database/tables from CodeScript.Globals
// this.debugGlobalState(script.Globals);
// get current command
var cursorOffset = document.offsetAt(position);
var currentCommand = script.GetBlockAtPosition(cursorOffset);
var completionItems = currentCommand.Service.GetCompletionItems(cursorOffset, this._completionOptions);
var disabledItems = this.disabledCompletionItemsV2;
if (this._languageSettings.disabledCompletionItems) {
this._languageSettings.disabledCompletionItems.map(function (item) {
// logic will treat unknown as a '*' wildcard, meaning that if the key is in the object
// the completion item will be suppressed.
disabledItems[item] = k2.CompletionKind.Unknown;
});
}
var itemsAsArray = this.toArray(completionItems.Items);
var items = itemsAsArray
.filter(function (item) {
return !(item &&
item.MatchText &&
disabledItems[item.MatchText] !== undefined &&
(disabledItems[item.MatchText] === k2.CompletionKind.Unknown ||
disabledItems[item.MatchText] === item.Kind));
})
.map(function (kItem, index) {
var v1CompletionOption = new k.CompletionOption(_this._toOptionKind[kItem.Kind] || k.OptionKind.None, kItem.DisplayText);
var helpTopic = _this.getTopic(v1CompletionOption);
// If we have AfterText it means that the cursor should not be placed at end of suggested text.
// In that case we switch to snippet format and represent the point where the cursor should be as
// as '\$0'
var _a = kItem.AfterText && kItem.AfterText.length > 0
? {
// Need to escape dollar sign since it is used as a placeholder in snippet.
// Usually dollar sign is not a valid character in a function name, but grafana uses macros that start with dollars.
textToInsert: "".concat(kItem.EditText.replace('$', '\\$'), "$0").concat(kItem.AfterText),
format: ls.InsertTextFormat.Snippet,
}
: {
textToInsert: kItem.EditText,
format: ls.InsertTextFormat.PlainText,
}, textToInsert = _a.textToInsert, format = _a.format;
var lsItem = ls.CompletionItem.create(kItem.DisplayText);
var startPosition = document.positionAt(completionItems.EditStart);
var endPosition = document.positionAt(completionItems.EditStart + completionItems.EditLength);
lsItem.textEdit = ls.TextEdit.replace(ls.Range.create(startPosition, endPosition), textToInsert);
// Changing the first letter to be lower case, to ignore case-sensitive matching
lsItem.filterText = kItem.MatchText.charAt(0).toLowerCase() + kItem.MatchText.slice(1);
lsItem.kind = _this.kustoKindToLsKindV2(kItem.Kind);
lsItem.sortText = kItem.OrderText;
lsItem.insertTextFormat = format;
lsItem.detail = helpTopic ? helpTopic.ShortDescription : undefined;
lsItem.documentation = helpTopic
? { value: _this.formatHelpTopic(helpTopic), kind: ls.MarkupKind.Markdown }
: undefined;
return lsItem;
});
return Promise.resolve(ls.CompletionList.create(items));
};
/**
* when trying to get a topic we need the function name (abs, toLower, ETC).
* The problem is that the 'Value' string also contains the arguments (e.g abs(number)), which means that we are
* not able to correlate the option with its documentation.
* This piece of code tries to strip this hwne getting topic.
* @param completionOption the Completion option
*/
KustoLanguageService.prototype.getTopic = function (completionOption) {
if (completionOption.Kind == k.OptionKind.FunctionScalar ||
completionOption.Kind == k.OptionKind.FunctionAggregation) {
// from a value like 'abs(number)' remove the '(number)' so that only 'abs' will remain
var indexOfParen = completionOption.Value.indexOf('(');
if (indexOfParen >= 0) {
completionOption = new k.CompletionOption(completionOption.Kind, completionOption.Value.substring(0, indexOfParen));
}
}
return k.CslDocumentation.Instance.GetTopic(completionOption);
};
KustoLanguageService.prototype.doRangeFormat = function (document, range) {
if (!document) {
return Promise.resolve([]);
}
var rangeStartOffset = document.offsetAt(range.start);
var rangeEndOffset = document.offsetAt(range.end);
var commands = this.getFormattedCommandsInDocumentV2(document, rangeStartOffset, rangeEndOffset);
if (!commands.originalRange || commands.formattedCommands.length === 0) {
return Promise.resolve([]);
}
return Promise.resolve([ls.TextEdit.replace(commands.originalRange, commands.formattedCommands.join(''))]);
};
KustoLanguageService.prototype.doDocumentFormat = function (document) {
if (!document) {
return Promise.resolve([]);
}
var startPos = document.positionAt(0);
var endPos = document.positionAt(document.getText().length);
var fullDocRange = ls.Range.create(startPos, endPos);
var formattedDoc = this.getFormattedCommandsInDocumentV2(document).formattedCommands.join('');
return Promise.resolve([ls.TextEdit.replace(fullDocRange, formattedDoc)]);
};
// Method is not triggered, instead doRangeFormat is invoked with the range of the caret's line.
KustoLanguageService.prototype.doCurrentCommandFormat = function (document, caretPosition) {
var offset = document.offsetAt(caretPosition);
var range = this.createRange(document, offset - 1, offset + 1);
return this.doRangeFormat(document, range);
};
KustoLanguageService.prototype.doFolding = function (document) {
if (!document) {
return Promise.resolve([]);
}
return this.getCommandsInDocument(document).then(function (commands) {
return commands.map(function (command) {
// don't count the last empty line as part of the folded range (consider linux, mac, pc newlines)
if (command.text.endsWith('\r\n')) {
command.absoluteEnd -= 2;
}
else if (command.text.endsWith('\r') || command.text.endsWith('\n')) {
--command.absoluteEnd;
}
var startPosition = document.positionAt(command.absoluteStart);
var endPosition = document.positionAt(command.absoluteEnd);
return {
startLine: startPosition.line,
startCharacter: startPosition.character,
endLine: endPosition.line,
endCharacter: endPosition.character,
};
});
});
};
KustoLanguageService.prototype.getClusterReferences = function (document, cursorOffset) {
var _a;
var script = this.parseDocumentV2(document);
var currentBlock = this.getCurrentCommandV2(script, cursorOffset);
var clusterReferences = (_a = currentBlock === null || currentBlock === void 0 ? void 0 : currentBlock.Service) === null || _a === void 0 ? void 0 : _a.GetClusterReferences();
if (!clusterReferences) {
return Promise.resolve([]);
}
var newClustersReferencesSet = new Set(); // used to remove duplicates
// Keep only unique clusters that aren't already exist in the Global State
for (var i = 0; i < clusterReferences.Count; i++) {
var clusterReference = clusterReferences.getItem(i);
// Because the engine client adds suffix anyway
// const clusterName = Kusto.Language.KustoFacts.GetFullHostName(clusterReference.Cluster, Kusto.Language.KustoFacts.KustoWindowsNet);
var clusterName = Kusto.Language.KustoFacts.GetFullHostName(clusterReference.Cluster, null);
if (!this._clustersSetInGlobalState.has(clusterName)) {
newClustersReferencesSet.add(clusterName);
}
}
return Promise.resolve(Array.from(newClustersReferencesSet).map(function (clusterName) { return ({ clusterName: clusterName }); }));
};
KustoLanguageService.prototype.getDatabaseReferences = function (document, cursorOffset) {
var _a;
var script = this.parseDocumentV2(document);
var currentBlock = this.getCurrentCommandV2(script, cursorOffset);
var databasesReferences = (_a = currentBlock === null || currentBlock === void 0 ? void 0 : currentBlock.Service) === null || _a === void 0 ? void 0 : _a.GetDatabaseReferences();
if (!databasesReferences) {
return Promise.resolve([]);
}
var newDatabasesReferences = [];
var newDatabasesReferencesSet = new Set();
for (var i1 = 0; i1 < databasesReferences.Count; i1++) {
var databaseReference = databasesReferences.getItem(i1);
var clusterHostName = Kusto.Language.KustoFacts.GetFullHostName(databaseReference.Cluster, null);
// ignore duplicates
var databaseReferenceUniqueId = this.createDatabaseUniqueName(clusterHostName, databaseReference.Database);
if (newDatabasesReferencesSet.has(databaseReferenceUniqueId)) {
continue;
}
newDatabasesReferencesSet.add(databaseReferenceUniqueId);
// ignore references that are already in the GlobalState.
var foundInGlobalState = this._nonEmptyDatabaseSetInGlobalState.has(databaseReferenceUniqueId);
if (!foundInGlobalState) {
newDatabasesReferences.push({
databaseName: databaseReference.Database,
clusterName: clusterHostName,
});
}
}
return Promise.resolve(newDatabasesReferences);
};
KustoLanguageService.prototype.doValidation = function (document, changeIntervals, includeWarnings, includeSuggestions) {
var _this = this;
// didn't implement validation for v1.
if (!document) {
return Promise.resolve([]);
}
var script = this.parseDocumentV2(document);
var blocks = this.toArray(script.Blocks);
if (changeIntervals.length > 0) {
blocks = this.getAffectedBlocks(blocks, changeIntervals);
}
var diagnostics = blocks
.map(function (block) {
// GetDiagnostics returns the errors in the block
var diagnostics = _this.toArray(block.Service.GetDiagnostics());
var enableWarnings = includeWarnings !== null && includeWarnings !== void 0 ? includeWarnings : _this._languageSettings.enableQueryWarnings;
var enableSuggestions = includeSuggestions !== null && includeSuggestions !== void 0 ? includeSuggestions : _this._languageSettings.enableQuerySuggestions;
if (enableWarnings || enableSuggestions) {
// Concat Warnings and suggestions to the diagnostics
var warningAndSuggestionDiagnostics = block.Service.GetAnalyzerDiagnostics(true);
var filterredDiagnostics = _this.toArray(warningAndSuggestionDiagnostics).filter(function (d) {
var _a;
var allowSeverity = (enableWarnings && d.Severity === 'Warning') ||
(enableSuggestions && d.Severity === 'Suggestion');
var allowCode = !((_a = _this._languageSettings.disabledDiagnosticCodes) === null || _a === void 0 ? void 0 : _a.includes(d.Code));
return allowSeverity && allowCode;
});
diagnostics = diagnostics.concat(filterredDiagnostics);
}
return diagnostics;
})
.reduce(function (prev, curr) { return prev.concat(curr); }, []);
var lsDiagnostics = this.toLsDiagnostics(diagnostics, document);
return Promise.resolve(lsDiagnostics);
};
KustoLanguageService.prototype.getApplyCodeActions = function (document, start, end) {
var script = this.parseDocumentV2(document);
var block = this.getAffectedBlocks(this.toArray(script.Blocks), [{ start: start, end: end }])[0];
var codeActionInfo = block.Service.GetCodeActions(start, start, 0, null, true, null, new Kusto.Language.Utils.CancellationToken());
var codeActions = this.toArray(codeActionInfo.Actions);
// Some code actions are of type "MenuAction". We want to flat them out, to show them seperately.
var flatCodeActions = [];
for (var i = 0; i < codeActions.length; i++) {
flatCodeActions.push.apply(flatCodeActions, this.flattenCodeActions(codeActions[i], null));
}
return flatCodeActions;
};
KustoLanguageService.prototype.getResultActions = function (document, start, end) {
var _this = this;
var script = this.parseDocumentV2(document);
var block = this.getAffectedBlocks(this.toArray(script.Blocks), [{ start: start, end: end }])[0];
var applyCodeActions = this.getApplyCodeActions(document, start, end);
var resultActionsMap = applyCodeActions
.map(function (applyCodeAction) {
var changes = [];
var codeActionResults = _this.toArray(block.Service.ApplyCodeAction(applyCodeAction, start).Actions);
var changeTextAction = codeActionResults.find(function (c) { return c instanceof Kusto.Language.Editor.ChangeTextAction; });
if (changeTextAction) {
changes = _this.toArray(changeTextAction.Changes).map(function (change) { return ({
start: change.Start + block.Start,
deleteLength: change.DeleteLength,
insertText: change.InsertText,
}); });
}
return { title: applyCodeAction.Title, changes: changes, kind: applyCodeAction.Kind };
})
.filter(function (resultAction) { return resultAction.changes.length; });
return Promise.resolve(resultActionsMap);
};
KustoLanguageService.prototype.transformCodeActionTitle = function (currentActionTitle, parentActionTitle) {
var title = currentActionTitle;
switch (title) {
case 'Apply':
title = 'Apply once';
break;
case 'Fix All':
title = 'Apply to all';
break;
case 'Extract Value':
title = 'Extract value';
break;
}
if (parentActionTitle) {
// We want to lower case the first character since it's going to be in brackets
var parentActionTitleLowerCased = parentActionTitle.charAt(0).toUpperCase() + parentActionTitle.slice(1);
title = "".concat(title, " (").concat(parentActionTitleLowerCased, ")");
}
return title;
};
KustoLanguageService.prototype.flattenCodeActions = function (codeAction, parentTitle) {
var applyActions = [];
if (codeAction instanceof k2.ApplyAction) {
codeAction.Title = this.transformCodeActionTitle(codeAction.Title, parentTitle);
applyActions.push(codeAction);
}
else if (codeAction instanceof k2.MenuAction) {
var nestedCodeActions = this.toArray(codeAction.Actions);
for (var i = 0; i < nestedCodeActions.length; i++) {
applyActions.push.apply(applyActions, this.flattenCodeActions(nestedCodeActions[i], codeAction.Title));
}
}
return applyActions;
};
KustoLanguageService.prototype.toLsDiagnostics = function (diagnostics, document) {
return diagnostics
.filter(function (diag) { return diag.HasLocation; })
.map(function (diag) {
var start = document.positionAt(diag.Start);
var end = document.positionAt(diag.Start + diag.Length);
var range = ls.Range.create(start, end);
var severity;
switch (diag.Severity) {
case 'Suggestion':
severity = ls.DiagnosticSeverity.Information;
break;
case 'Warning':
severity = ls.DiagnosticSeverity.Warning;
break;
default:
severity = ls.DiagnosticSeverity.Error;
}
return ls.Diagnostic.create(range, diag.Message, severity, diag.Code);
});
};
KustoLanguageService.prototype.getClassifications = function (document) {
return __awaiter(this, void 0, void 0, function () {
var codeScript, codeBlocks, classificationRanges;
var _this = this;
return __generator(this, function (_a) {
codeScript = this.parseDocumentV2(document);
codeBlocks = this.toArray(codeScript.Blocks);
classificationRanges = codeBlocks.map(function (block) {
var Classifications = block.Service.GetClassifications(block.Start, block.Length).Classifications;
return _this.toArray(Classifications);
});
return [2 /*return*/, classificationRanges.flatMap(function (ranges) {
return ranges.map(function (range) {
var _a = document.positionAt(range.Start), line = _a.line, character = _a.character;
var length = range.Length;
var kind = range.Kind;
return { line: line, character: character, length: length, kind: kind };
});
})];
});
});
};
KustoLanguageService.prototype.getAffectedBlocks = function (blocks, changeIntervals) {
return blocks.filter(function (block) {
// a command is affected if it intersects at least on of changed ranges.
return block // command can be null. we're filtering all nulls in the array.
? changeIntervals.some(function (_a) {
var changeStart = _a.start, changeEnd = _a.end;
// both intervals intersect if either the start or the end of interval A is inside interval B.
return (block.Start >= changeStart && block.Start <= changeEnd) ||
(changeStart >= block.Start && changeStart <= block.End + 1);
})
: false;
});
};
KustoLanguageService.prototype.addClusterToSchema = function (document, clusterName, databases) {
var clusterNameOnly = Kusto.Language.KustoFacts.GetHostName(clusterName);
var cluster = this._kustoJsSchemaV2.GetCluster$1(clusterNameOnly);
if (cluster) {
// add databases that are not already in the cluster.
databases
.filter(function (_a) {
var name = _a.name;
return !cluster.GetDatabase(name);
})
.forEach(function (_a) {
var name = _a.name, alternativeName = _a.alternativeName;
var symbol = new sym.DatabaseSymbol.$ctor3(name, alternativeName || null, undefined, false);
cluster = cluster.AddDatabase(symbol);
});
}
if (!cluster) {
var databaseSymbols = databases.map(function (_a) {
var name = _a.name, alternativeName = _a.alternativeName;
return new sym.DatabaseSymbol.$ctor3(name, alternativeName || null, undefined, false);
});
var databaseSymbolsList = new (List(sym.DatabaseSymbol).$ctor1)(databaseSymbols);
cluster = new sym.ClusterSymbol.$ctor1(clusterNameOnly, databaseSymbolsList, false);
}
this._kustoJsSchemaV2 = this._kustoJsSchemaV2.AddOrReplaceCluster(cluster);
this._script = k2.CodeScript.From$1(document.getText(), this._kustoJsSchemaV2);
return Promise.resolve();
};
KustoLanguageService.prototype.addDatabaseToSchema = function (document, clusterName, databaseSchema) {
var clusterHostName = Kusto.Language.KustoFacts.GetHostName(clusterName);
var cluster = this._kustoJsSchemaV2.GetCluster$1(clusterHostName);
if (!cluster) {
cluster = new sym.ClusterSymbol.$ctor1(clusterHostName, null, false);
}
var databaseSymbol = KustoLanguageService.convertToDatabaseSymbol(databaseSchema);
cluster = cluster.AddOrUpdateDatabase(databaseSymbol);
this._kustoJsSchemaV2 = this._kustoJsSchemaV2.AddOrReplaceCluster(cluster);
this._script = k2.CodeScript.From$1(document.getText(), this._kustoJsSchemaV2);
return Promise.resolve();
};
KustoLanguageService.prototype.setSchema = function (schema) {
this._schema = schema;
// We support intellisenseV2 only if the clusterType is "Engine", even if the setting is enabled
if (schema && schema.clusterType === 'Engine') {
var kustoJsSchemaV2 = this.convertToKustoJsSchemaV2(schema);
this._kustoJsSchemaV2 = kustoJsSchemaV2;
this._script = undefined;
this._parsePropertiesV2 = undefined;
}
// since V2 doesn't support control commands, we're initializing V1 intellisense for both cases and we'll going to use V1 intellisense for control commands.
var kustoJsSchema = schema ? KustoLanguageService.convertToKustoJsSchema(schema) : undefined;
this._kustoJsSchema = kustoJsSchema;
this.createRulesProvider(kustoJsSchema, schema.clusterType);
return Promise.resolve();
};
KustoLanguageService.prototype.setParameters = function (scalarParameters, tabularParameters) {
var _a;
if (this._schema.clusterType !== 'Engine') {
throw new Error('setParameters requires intellisense V2 and Engine cluster');
}
this._schema.globalScalarParameters = scalarParameters;
this._schema.globalTabularParameters = tabularParameters;
var scalarSymbols = scalarParameters.map(function (param) { return KustoLanguageService.createParameterSymbol(param); });
var tabularSymbols = tabularParameters.map(function (param) {
return KustoLanguageService.createTabularParameterSymbol(param);
});
this._kustoJsSchemaV2 = this._kustoJsSchemaV2.WithParameters(KustoLanguageService.toBridgeList(__spreadArray(__spreadArray([], scalarSymbols, true), tabularSymbols, true)));
this._script = (_a = this._script) === null || _a === void 0 ? void 0 : _a.WithGlobals(this._kustoJsSchemaV2);
// Set parameters is only working with the below code. It didn't used to need this, why does it now?!?
// Copy+pasted from setSchema
var kustoJsSchema = KustoLanguageService.convertToKustoJsSchema(this._schema);
this._kustoJsSchema = kustoJsSchema;
this.createRulesProvider(kustoJsSchema, this._schema.clusterType);
return Promise.resolve(undefined);
};
/**
* A combination of normalizeSchema and setSchema
* @param schema schema json as received from .show schema as json
* @param clusterConnectionString cluster connection string
* @param databaseInContextName name of database in context
* @param globalScalarParameters
* @param globalTabularParameters
* @param databaseInContextAlternateName alternate name of database in context
*/
KustoLanguageService.prototype.setSchemaFromShowSchema = function (schema, clusterConnectionString, databaseInContextName, globalScalarParameters, globalTabularParameters, databaseInContextAlternateName) {
var normalized = this._normalizeSchema(schema, clusterConnectionString, databaseInContextName, databaseInContextAlternateName);
return this.setSchema(__assign(__assign({}, normalized), { globalScalarParameters: globalScalarParameters, globalTabularParameters: globalTabularParameters }));
};
/**
* Converts the result of .show schema as json to a normalized schema used by kusto language service.
* @param schema result of show schema
* @param clusterConnectionString cluster connection string`
* @param databaseInContextName database in context name
* @param databaseInContextAlternateName database in context alternate name
*/
KustoLanguageService.prototype._normalizeSchema = function (schema, clusterConnectionString, databaseInContextName, databaseInContextAlternateName) {
var databases = Object.keys(schema.Databases)
.map(function (key) { return schema.Databases[key]; })
.map(function (_a) {
var Name = _a.Name, Tables = _a.Tables, ExternalTables = _a.ExternalTables, MaterializedViews = _a.MaterializedViews, Functions = _a.Functions, _b = _a.EntityGroups, EntityGroups = _b === void 0 ? {} : _b, MinorVersion = _a.MinorVersion, MajorVersion = _a.MajorVersion;
return ({
name: Name,
alternateName: databaseInContextAlternateName,
minorVersion: MinorVersion,
majorVersion: MajorVersion,
entityGroups: Object.entries(EntityGroups).map(function (_a) {
var name = _a[0], members = _a[1];
return ({
name: name,
members: members,
});
}),
tables: [].concat.apply([], [
[Tables, 'Table'],
[MaterializedViews, 'MaterializedView'],
[ExternalTables, 'ExternalTable'],
]
.filter(function (_a) {
var tableContainer = _a[0];
return tableContainer;
})
.map(function (_a) {
var tableContainer = _a[0], tableEntity = _a[1];
return Object.values(tableContainer).map(function (_a) {
var Name = _a.Name, OrderedColumns = _a.OrderedColumns, DocString = _a.DocString;
return ({
name: Name,
docstring: DocString,
entityType: tableEntity,
columns: OrderedColumns.map(function (_a) {
var Name = _a.Name, Type = _a.Type, DocString = _a.DocString, CslType = _a.CslType, Examples = _a.Examples;
return ({
name: Name,
type: CslType,
docstring: DocString,
examples: Examples,
});
}),
});
});
})),
functions: Object.keys(Functions)
.map(function (key) { return Functions[key]; })
.map(function (_a) {
var Name = _a.Name, Body = _a.Body, DocString = _a.DocString, InputParameters = _a.InputParameters;
return ({
name: Nam