notes/coc/extensions/node_modules/coc-emmet/lib/index.js

8638 lines
No EOL
295 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(function(e, a) { for(var i in a) e[i] = a[i]; }(exports, /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const coc_nvim_1 = __webpack_require__(1);
const defaultCompletionProvider_1 = __webpack_require__(2);
const util_1 = __webpack_require__(32);
function activate(context) {
registerCompletionProviders(context);
context.subscriptions.push(coc_nvim_1.workspace.onDidChangeConfiguration(e => {
if (e.affectsConfiguration('emmet.includeLanguages')) {
registerCompletionProviders(context);
}
}));
coc_nvim_1.workspace.onDidOpenTextDocument(() => {
registerCompletionProviders(context);
}, null, context.subscriptions);
}
exports.activate = activate;
/**
* Holds any registered completion providers by their language strings
*/
const registeredModes = new Set();
function registerCompletionProviders(context) {
let includedLanguages = util_1.getMappingForIncludedLanguages();
let current_languages = coc_nvim_1.workspace.filetypes;
const emmetConfig = coc_nvim_1.workspace.getConfiguration('emmet');
for (let language of current_languages) {
let emmetMode = Object.keys(util_1.LANGUAGE_MODES).find(s => s == language) || includedLanguages[language];
if (!emmetMode || registeredModes.has(emmetMode))
continue;
registeredModes.add(emmetMode);
let filetypes = [emmetMode];
if (emmetMode != language) {
filetypes.push(language);
}
for (let key of Object.keys(includedLanguages)) {
let val = includedLanguages[key];
if (val == emmetMode && filetypes.indexOf(val) == -1) {
filetypes.push(val);
}
}
let completionProvider = new defaultCompletionProvider_1.DefaultCompletionItemProvider();
const provider = coc_nvim_1.languages.registerCompletionItemProvider(`emmet-${emmetMode}`, 'EM', filetypes, completionProvider, util_1.LANGUAGE_MODES[emmetMode], emmetConfig.get('priority', 3));
context.subscriptions.push(provider);
}
}
/***/ }),
/* 1 */
/***/ (function(module, exports) {
module.exports = require("coc.nvim");
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const coc_nvim_1 = __webpack_require__(1);
const vscode_languageserver_protocol_1 = __webpack_require__(3);
const abbreviationActions_1 = __webpack_require__(31);
const util_1 = __webpack_require__(32);
class DefaultCompletionItemProvider {
resolveCompletionItem(item) {
if (item.data) {
const { textEdit } = item.data;
item.textEdit = textEdit;
delete item.data.textEdit;
}
return item;
}
provideCompletionItems(document, position, _, context) {
const completionResult = this.provideCompletionItemsInternal(document, position, context);
if (!completionResult) {
this.lastCompletionType = undefined;
return;
}
return completionResult.then(completionList => {
if (!completionList || !completionList.items.length) {
this.lastCompletionType = undefined;
return null;
}
const item = completionList.items[0];
const expandedText = item.documentation ? item.documentation.toString() : '';
if (expandedText.startsWith('<')) {
this.lastCompletionType = 'html';
}
else if (expandedText.indexOf(':') > 0 && expandedText.endsWith(';')) {
this.lastCompletionType = 'css';
}
else {
this.lastCompletionType = undefined;
}
return completionList;
});
}
provideCompletionItemsInternal(document, position, context) {
const emmetConfig = coc_nvim_1.workspace.getConfiguration('emmet');
const excludedLanguages = emmetConfig['excludeLanguages'] ? emmetConfig['excludeLanguages'] : [];
if (excludedLanguages.indexOf(document.languageId) > -1) {
return;
}
const mappedLanguages = util_1.getMappingForIncludedLanguages();
const isSyntaxMapped = mappedLanguages[document.languageId] ? true : false;
let syntax = util_1.getEmmetMode((isSyntaxMapped ? mappedLanguages[document.languageId] : document.languageId), excludedLanguages);
if (!syntax || emmetConfig['showExpandedAbbreviation'] === 'never') {
return;
}
const helper = util_1.getEmmetHelper();
let validateLocation = syntax === 'html' || syntax === 'jsx' || syntax === 'xml';
let rootNode;
let currentNode = null;
if (document.languageId === 'html') {
if (context.triggerKind === vscode_languageserver_protocol_1.CompletionTriggerKind.TriggerForIncompleteCompletions) {
switch (this.lastCompletionType) {
case 'html':
validateLocation = false;
break;
case 'css':
validateLocation = false;
syntax = 'css';
break;
default:
break;
}
}
if (validateLocation) {
rootNode = util_1.parseDocument(document, false);
currentNode = util_1.getNode(rootNode, position, true);
if (util_1.isStyleAttribute(currentNode, position)) {
syntax = 'css';
validateLocation = false;
}
else {
const embeddedCssNode = util_1.getEmbeddedCssNodeIfAny(document, currentNode, position);
if (embeddedCssNode) {
currentNode = util_1.getNode(embeddedCssNode, position, true);
syntax = 'css';
}
}
}
}
const extractAbbreviationResults = helper.extractAbbreviation(document, position, !util_1.isStyleSheet(syntax));
if (!extractAbbreviationResults || !helper.isAbbreviationValid(syntax, extractAbbreviationResults.abbreviation)) {
return;
}
if (util_1.isStyleSheet(document.languageId) && context.triggerKind !== vscode_languageserver_protocol_1.CompletionTriggerKind.TriggerForIncompleteCompletions) {
validateLocation = true;
let usePartialParsing = coc_nvim_1.workspace.getConfiguration('emmet')['optimizeStylesheetParsing'] === true;
rootNode = usePartialParsing && document.lineCount > 1000 ? util_1.parsePartialStylesheet(document, position) : util_1.parseDocument(document, false);
if (!rootNode) {
return;
}
currentNode = util_1.getNode(rootNode, position, true);
}
if (validateLocation && !abbreviationActions_1.isValidLocationForEmmetAbbreviation(document, rootNode, currentNode, syntax, position, extractAbbreviationResults.abbreviationRange)) {
return;
}
let noiseCheckPromise = Promise.resolve();
// Fix for https://github.com/Microsoft/issues/32647
// Check for document symbols in js/ts/jsx/tsx and avoid triggering emmet for abbreviations of the form symbolName.sometext
// Presence of > or * or + in the abbreviation denotes valid abbreviation that should trigger emmet
if (!util_1.isStyleSheet(syntax) && (document.languageId === 'javascript' || document.languageId === 'javascriptreact' || document.languageId === 'typescript' || document.languageId === 'typescriptreact')) {
let abbreviation = extractAbbreviationResults.abbreviation;
if (abbreviation.startsWith('this.')) {
noiseCheckPromise = Promise.resolve(true);
}
}
return noiseCheckPromise.then((noise) => {
if (noise) {
return;
}
let result = helper.doComplete(document, position, syntax, util_1.getEmmetConfiguration(syntax));
let newItems = [];
let { option } = context;
if (result && result.items) {
result.items.forEach((item) => {
let newItem = { label: item.label };
newItem.documentation = item.documentation;
newItem.detail = item.detail;
newItem.insertTextFormat = vscode_languageserver_protocol_1.InsertTextFormat.Snippet;
let oldrange = item.textEdit.range;
const textEdit = {
range: vscode_languageserver_protocol_1.Range.create(oldrange.start.line, oldrange.start.character, oldrange.end.line, oldrange.end.character),
newText: item.textEdit.newText
};
if (emmetConfig['showSuggestionsAsSnippets'] === true) {
newItem.kind = vscode_languageserver_protocol_1.CompletionItemKind.Snippet;
}
newItem.filterText = option ? option.input : item.word;
newItem.data = {
word: newItem.filterText,
textEdit
};
newItem.sortText = item.sortText;
newItems.push(newItem);
});
}
return {
items: newItems,
engross: false,
isIncomplete: true
};
});
}
}
exports.DefaultCompletionItemProvider = DefaultCompletionItemProvider;
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_jsonrpc_1 = __webpack_require__(4);
exports.ErrorCodes = vscode_jsonrpc_1.ErrorCodes;
exports.ResponseError = vscode_jsonrpc_1.ResponseError;
exports.CancellationToken = vscode_jsonrpc_1.CancellationToken;
exports.CancellationTokenSource = vscode_jsonrpc_1.CancellationTokenSource;
exports.Disposable = vscode_jsonrpc_1.Disposable;
exports.Event = vscode_jsonrpc_1.Event;
exports.Emitter = vscode_jsonrpc_1.Emitter;
exports.Trace = vscode_jsonrpc_1.Trace;
exports.TraceFormat = vscode_jsonrpc_1.TraceFormat;
exports.SetTraceNotification = vscode_jsonrpc_1.SetTraceNotification;
exports.LogTraceNotification = vscode_jsonrpc_1.LogTraceNotification;
exports.RequestType = vscode_jsonrpc_1.RequestType;
exports.RequestType0 = vscode_jsonrpc_1.RequestType0;
exports.NotificationType = vscode_jsonrpc_1.NotificationType;
exports.NotificationType0 = vscode_jsonrpc_1.NotificationType0;
exports.MessageReader = vscode_jsonrpc_1.MessageReader;
exports.MessageWriter = vscode_jsonrpc_1.MessageWriter;
exports.ConnectionStrategy = vscode_jsonrpc_1.ConnectionStrategy;
exports.StreamMessageReader = vscode_jsonrpc_1.StreamMessageReader;
exports.StreamMessageWriter = vscode_jsonrpc_1.StreamMessageWriter;
exports.IPCMessageReader = vscode_jsonrpc_1.IPCMessageReader;
exports.IPCMessageWriter = vscode_jsonrpc_1.IPCMessageWriter;
exports.createClientPipeTransport = vscode_jsonrpc_1.createClientPipeTransport;
exports.createServerPipeTransport = vscode_jsonrpc_1.createServerPipeTransport;
exports.generateRandomPipeName = vscode_jsonrpc_1.generateRandomPipeName;
exports.createClientSocketTransport = vscode_jsonrpc_1.createClientSocketTransport;
exports.createServerSocketTransport = vscode_jsonrpc_1.createServerSocketTransport;
__export(__webpack_require__(18));
__export(__webpack_require__(19));
const callHierarchy = __webpack_require__(28);
const progress = __webpack_require__(29);
const sr = __webpack_require__(30);
var Proposed;
(function (Proposed) {
let SelectionRangeRequest;
(function (SelectionRangeRequest) {
SelectionRangeRequest.type = sr.SelectionRangeRequest.type;
})(SelectionRangeRequest = Proposed.SelectionRangeRequest || (Proposed.SelectionRangeRequest = {}));
let CallHierarchyRequest;
(function (CallHierarchyRequest) {
CallHierarchyRequest.type = callHierarchy.CallHierarchyRequest.type;
})(CallHierarchyRequest = Proposed.CallHierarchyRequest || (Proposed.CallHierarchyRequest = {}));
let CallHierarchyDirection;
(function (CallHierarchyDirection) {
CallHierarchyDirection.CallsFrom = callHierarchy.CallHierarchyDirection.CallsFrom;
CallHierarchyDirection.CallsTo = callHierarchy.CallHierarchyDirection.CallsTo;
})(CallHierarchyDirection = Proposed.CallHierarchyDirection || (Proposed.CallHierarchyDirection = {}));
let ProgressStartNotification;
(function (ProgressStartNotification) {
ProgressStartNotification.type = progress.ProgressStartNotification.type;
})(ProgressStartNotification = Proposed.ProgressStartNotification || (Proposed.ProgressStartNotification = {}));
let ProgressReportNotification;
(function (ProgressReportNotification) {
ProgressReportNotification.type = progress.ProgressReportNotification.type;
})(ProgressReportNotification = Proposed.ProgressReportNotification || (Proposed.ProgressReportNotification = {}));
let ProgressDoneNotification;
(function (ProgressDoneNotification) {
ProgressDoneNotification.type = progress.ProgressDoneNotification.type;
})(ProgressDoneNotification = Proposed.ProgressDoneNotification || (Proposed.ProgressDoneNotification = {}));
let ProgressCancelNotification;
(function (ProgressCancelNotification) {
ProgressCancelNotification.type = progress.ProgressCancelNotification.type;
})(ProgressCancelNotification = Proposed.ProgressCancelNotification || (Proposed.ProgressCancelNotification = {}));
})(Proposed = exports.Proposed || (exports.Proposed = {}));
function createProtocolConnection(reader, writer, logger, strategy) {
return vscode_jsonrpc_1.createMessageConnection(reader, writer, logger, strategy);
}
exports.createProtocolConnection = createProtocolConnection;
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
/// <reference path="./thenable.ts" />
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
const Is = __webpack_require__(5);
const messages_1 = __webpack_require__(6);
exports.RequestType = messages_1.RequestType;
exports.RequestType0 = messages_1.RequestType0;
exports.RequestType1 = messages_1.RequestType1;
exports.RequestType2 = messages_1.RequestType2;
exports.RequestType3 = messages_1.RequestType3;
exports.RequestType4 = messages_1.RequestType4;
exports.RequestType5 = messages_1.RequestType5;
exports.RequestType6 = messages_1.RequestType6;
exports.RequestType7 = messages_1.RequestType7;
exports.RequestType8 = messages_1.RequestType8;
exports.RequestType9 = messages_1.RequestType9;
exports.ResponseError = messages_1.ResponseError;
exports.ErrorCodes = messages_1.ErrorCodes;
exports.NotificationType = messages_1.NotificationType;
exports.NotificationType0 = messages_1.NotificationType0;
exports.NotificationType1 = messages_1.NotificationType1;
exports.NotificationType2 = messages_1.NotificationType2;
exports.NotificationType3 = messages_1.NotificationType3;
exports.NotificationType4 = messages_1.NotificationType4;
exports.NotificationType5 = messages_1.NotificationType5;
exports.NotificationType6 = messages_1.NotificationType6;
exports.NotificationType7 = messages_1.NotificationType7;
exports.NotificationType8 = messages_1.NotificationType8;
exports.NotificationType9 = messages_1.NotificationType9;
const messageReader_1 = __webpack_require__(7);
exports.MessageReader = messageReader_1.MessageReader;
exports.StreamMessageReader = messageReader_1.StreamMessageReader;
exports.IPCMessageReader = messageReader_1.IPCMessageReader;
exports.SocketMessageReader = messageReader_1.SocketMessageReader;
const messageWriter_1 = __webpack_require__(9);
exports.MessageWriter = messageWriter_1.MessageWriter;
exports.StreamMessageWriter = messageWriter_1.StreamMessageWriter;
exports.IPCMessageWriter = messageWriter_1.IPCMessageWriter;
exports.SocketMessageWriter = messageWriter_1.SocketMessageWriter;
const events_1 = __webpack_require__(8);
exports.Disposable = events_1.Disposable;
exports.Event = events_1.Event;
exports.Emitter = events_1.Emitter;
const cancellation_1 = __webpack_require__(10);
exports.CancellationTokenSource = cancellation_1.CancellationTokenSource;
exports.CancellationToken = cancellation_1.CancellationToken;
const linkedMap_1 = __webpack_require__(11);
__export(__webpack_require__(12));
__export(__webpack_require__(17));
var CancelNotification;
(function (CancelNotification) {
CancelNotification.type = new messages_1.NotificationType('$/cancelRequest');
})(CancelNotification || (CancelNotification = {}));
exports.NullLogger = Object.freeze({
error: () => { },
warn: () => { },
info: () => { },
log: () => { }
});
var Trace;
(function (Trace) {
Trace[Trace["Off"] = 0] = "Off";
Trace[Trace["Messages"] = 1] = "Messages";
Trace[Trace["Verbose"] = 2] = "Verbose";
})(Trace = exports.Trace || (exports.Trace = {}));
(function (Trace) {
function fromString(value) {
value = value.toLowerCase();
switch (value) {
case 'off':
return Trace.Off;
case 'messages':
return Trace.Messages;
case 'verbose':
return Trace.Verbose;
default:
return Trace.Off;
}
}
Trace.fromString = fromString;
function toString(value) {
switch (value) {
case Trace.Off:
return 'off';
case Trace.Messages:
return 'messages';
case Trace.Verbose:
return 'verbose';
default:
return 'off';
}
}
Trace.toString = toString;
})(Trace = exports.Trace || (exports.Trace = {}));
var TraceFormat;
(function (TraceFormat) {
TraceFormat["Text"] = "text";
TraceFormat["JSON"] = "json";
})(TraceFormat = exports.TraceFormat || (exports.TraceFormat = {}));
(function (TraceFormat) {
function fromString(value) {
value = value.toLowerCase();
if (value === 'json') {
return TraceFormat.JSON;
}
else {
return TraceFormat.Text;
}
}
TraceFormat.fromString = fromString;
})(TraceFormat = exports.TraceFormat || (exports.TraceFormat = {}));
var SetTraceNotification;
(function (SetTraceNotification) {
SetTraceNotification.type = new messages_1.NotificationType('$/setTraceNotification');
})(SetTraceNotification = exports.SetTraceNotification || (exports.SetTraceNotification = {}));
var LogTraceNotification;
(function (LogTraceNotification) {
LogTraceNotification.type = new messages_1.NotificationType('$/logTraceNotification');
})(LogTraceNotification = exports.LogTraceNotification || (exports.LogTraceNotification = {}));
var ConnectionErrors;
(function (ConnectionErrors) {
/**
* The connection is closed.
*/
ConnectionErrors[ConnectionErrors["Closed"] = 1] = "Closed";
/**
* The connection got disposed.
*/
ConnectionErrors[ConnectionErrors["Disposed"] = 2] = "Disposed";
/**
* The connection is already in listening mode.
*/
ConnectionErrors[ConnectionErrors["AlreadyListening"] = 3] = "AlreadyListening";
})(ConnectionErrors = exports.ConnectionErrors || (exports.ConnectionErrors = {}));
class ConnectionError extends Error {
constructor(code, message) {
super(message);
this.code = code;
Object.setPrototypeOf(this, ConnectionError.prototype);
}
}
exports.ConnectionError = ConnectionError;
var ConnectionStrategy;
(function (ConnectionStrategy) {
function is(value) {
let candidate = value;
return candidate && Is.func(candidate.cancelUndispatched);
}
ConnectionStrategy.is = is;
})(ConnectionStrategy = exports.ConnectionStrategy || (exports.ConnectionStrategy = {}));
var ConnectionState;
(function (ConnectionState) {
ConnectionState[ConnectionState["New"] = 1] = "New";
ConnectionState[ConnectionState["Listening"] = 2] = "Listening";
ConnectionState[ConnectionState["Closed"] = 3] = "Closed";
ConnectionState[ConnectionState["Disposed"] = 4] = "Disposed";
})(ConnectionState || (ConnectionState = {}));
function _createMessageConnection(messageReader, messageWriter, logger, strategy) {
let sequenceNumber = 0;
let notificationSquenceNumber = 0;
let unknownResponseSquenceNumber = 0;
const version = '2.0';
let starRequestHandler = undefined;
let requestHandlers = Object.create(null);
let starNotificationHandler = undefined;
let notificationHandlers = Object.create(null);
let timer;
let messageQueue = new linkedMap_1.LinkedMap();
let responsePromises = Object.create(null);
let requestTokens = Object.create(null);
let trace = Trace.Off;
let traceFormat = TraceFormat.Text;
let tracer;
let state = ConnectionState.New;
let errorEmitter = new events_1.Emitter();
let closeEmitter = new events_1.Emitter();
let unhandledNotificationEmitter = new events_1.Emitter();
let disposeEmitter = new events_1.Emitter();
function createRequestQueueKey(id) {
return 'req-' + id.toString();
}
function createResponseQueueKey(id) {
if (id === null) {
return 'res-unknown-' + (++unknownResponseSquenceNumber).toString();
}
else {
return 'res-' + id.toString();
}
}
function createNotificationQueueKey() {
return 'not-' + (++notificationSquenceNumber).toString();
}
function addMessageToQueue(queue, message) {
if (messages_1.isRequestMessage(message)) {
queue.set(createRequestQueueKey(message.id), message);
}
else if (messages_1.isResponseMessage(message)) {
queue.set(createResponseQueueKey(message.id), message);
}
else {
queue.set(createNotificationQueueKey(), message);
}
}
function cancelUndispatched(_message) {
return undefined;
}
function isListening() {
return state === ConnectionState.Listening;
}
function isClosed() {
return state === ConnectionState.Closed;
}
function isDisposed() {
return state === ConnectionState.Disposed;
}
function closeHandler() {
if (state === ConnectionState.New || state === ConnectionState.Listening) {
state = ConnectionState.Closed;
closeEmitter.fire(undefined);
}
// If the connection is disposed don't sent close events.
}
;
function readErrorHandler(error) {
errorEmitter.fire([error, undefined, undefined]);
}
function writeErrorHandler(data) {
errorEmitter.fire(data);
}
messageReader.onClose(closeHandler);
messageReader.onError(readErrorHandler);
messageWriter.onClose(closeHandler);
messageWriter.onError(writeErrorHandler);
function triggerMessageQueue() {
if (timer || messageQueue.size === 0) {
return;
}
timer = setImmediate(() => {
timer = undefined;
processMessageQueue();
});
}
function processMessageQueue() {
if (messageQueue.size === 0) {
return;
}
let message = messageQueue.shift();
try {
if (messages_1.isRequestMessage(message)) {
handleRequest(message);
}
else if (messages_1.isNotificationMessage(message)) {
handleNotification(message);
}
else if (messages_1.isResponseMessage(message)) {
handleResponse(message);
}
else {
handleInvalidMessage(message);
}
}
finally {
triggerMessageQueue();
}
}
let callback = (message) => {
try {
// We have received a cancellation message. Check if the message is still in the queue
// and cancel it if allowed to do so.
if (messages_1.isNotificationMessage(message) && message.method === CancelNotification.type.method) {
let key = createRequestQueueKey(message.params.id);
let toCancel = messageQueue.get(key);
if (messages_1.isRequestMessage(toCancel)) {
let response = strategy && strategy.cancelUndispatched ? strategy.cancelUndispatched(toCancel, cancelUndispatched) : cancelUndispatched(toCancel);
if (response && (response.error !== void 0 || response.result !== void 0)) {
messageQueue.delete(key);
response.id = toCancel.id;
traceSendingResponse(response, message.method, Date.now());
messageWriter.write(response);
return;
}
}
}
addMessageToQueue(messageQueue, message);
}
finally {
triggerMessageQueue();
}
};
function handleRequest(requestMessage) {
if (isDisposed()) {
// we return here silently since we fired an event when the
// connection got disposed.
return;
}
function reply(resultOrError, method, startTime) {
let message = {
jsonrpc: version,
id: requestMessage.id
};
if (resultOrError instanceof messages_1.ResponseError) {
message.error = resultOrError.toJson();
}
else {
message.result = resultOrError === void 0 ? null : resultOrError;
}
traceSendingResponse(message, method, startTime);
messageWriter.write(message);
}
function replyError(error, method, startTime) {
let message = {
jsonrpc: version,
id: requestMessage.id,
error: error.toJson()
};
traceSendingResponse(message, method, startTime);
messageWriter.write(message);
}
function replySuccess(result, method, startTime) {
// The JSON RPC defines that a response must either have a result or an error
// So we can't treat undefined as a valid response result.
if (result === void 0) {
result = null;
}
let message = {
jsonrpc: version,
id: requestMessage.id,
result: result
};
traceSendingResponse(message, method, startTime);
messageWriter.write(message);
}
traceReceivedRequest(requestMessage);
let element = requestHandlers[requestMessage.method];
let type;
let requestHandler;
if (element) {
type = element.type;
requestHandler = element.handler;
}
let startTime = Date.now();
if (requestHandler || starRequestHandler) {
let cancellationSource = new cancellation_1.CancellationTokenSource();
let tokenKey = String(requestMessage.id);
requestTokens[tokenKey] = cancellationSource;
try {
let handlerResult;
if (requestMessage.params === void 0 || (type !== void 0 && type.numberOfParams === 0)) {
handlerResult = requestHandler
? requestHandler(cancellationSource.token)
: starRequestHandler(requestMessage.method, cancellationSource.token);
}
else if (Is.array(requestMessage.params) && (type === void 0 || type.numberOfParams > 1)) {
handlerResult = requestHandler
? requestHandler(...requestMessage.params, cancellationSource.token)
: starRequestHandler(requestMessage.method, ...requestMessage.params, cancellationSource.token);
}
else {
handlerResult = requestHandler
? requestHandler(requestMessage.params, cancellationSource.token)
: starRequestHandler(requestMessage.method, requestMessage.params, cancellationSource.token);
}
let promise = handlerResult;
if (!handlerResult) {
delete requestTokens[tokenKey];
replySuccess(handlerResult, requestMessage.method, startTime);
}
else if (promise.then) {
promise.then((resultOrError) => {
delete requestTokens[tokenKey];
reply(resultOrError, requestMessage.method, startTime);
}, error => {
delete requestTokens[tokenKey];
if (error instanceof messages_1.ResponseError) {
replyError(error, requestMessage.method, startTime);
}
else if (error && Is.string(error.message)) {
replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed with message: ${error.message}`), requestMessage.method, startTime);
}
else {
replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed unexpectedly without providing any details.`), requestMessage.method, startTime);
}
});
}
else {
delete requestTokens[tokenKey];
reply(handlerResult, requestMessage.method, startTime);
}
}
catch (error) {
delete requestTokens[tokenKey];
if (error instanceof messages_1.ResponseError) {
reply(error, requestMessage.method, startTime);
}
else if (error && Is.string(error.message)) {
replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed with message: ${error.message}`), requestMessage.method, startTime);
}
else {
replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed unexpectedly without providing any details.`), requestMessage.method, startTime);
}
}
}
else {
replyError(new messages_1.ResponseError(messages_1.ErrorCodes.MethodNotFound, `Unhandled method ${requestMessage.method}`), requestMessage.method, startTime);
}
}
function handleResponse(responseMessage) {
if (isDisposed()) {
// See handle request.
return;
}
if (responseMessage.id === null) {
if (responseMessage.error) {
logger.error(`Received response message without id: Error is: \n${JSON.stringify(responseMessage.error, undefined, 4)}`);
}
else {
logger.error(`Received response message without id. No further error information provided.`);
}
}
else {
let key = String(responseMessage.id);
let responsePromise = responsePromises[key];
traceReceivedResponse(responseMessage, responsePromise);
if (responsePromise) {
delete responsePromises[key];
try {
if (responseMessage.error) {
let error = responseMessage.error;
responsePromise.reject(new messages_1.ResponseError(error.code, error.message, error.data));
}
else if (responseMessage.result !== void 0) {
responsePromise.resolve(responseMessage.result);
}
else {
throw new Error('Should never happen.');
}
}
catch (error) {
if (error.message) {
logger.error(`Response handler '${responsePromise.method}' failed with message: ${error.message}`);
}
else {
logger.error(`Response handler '${responsePromise.method}' failed unexpectedly.`);
}
}
}
}
}
function handleNotification(message) {
if (isDisposed()) {
// See handle request.
return;
}
let type = undefined;
let notificationHandler;
if (message.method === CancelNotification.type.method) {
notificationHandler = (params) => {
let id = params.id;
let source = requestTokens[String(id)];
if (source) {
source.cancel();
}
};
}
else {
let element = notificationHandlers[message.method];
if (element) {
notificationHandler = element.handler;
type = element.type;
}
}
if (notificationHandler || starNotificationHandler) {
try {
traceReceivedNotification(message);
if (message.params === void 0 || (type !== void 0 && type.numberOfParams === 0)) {
notificationHandler ? notificationHandler() : starNotificationHandler(message.method);
}
else if (Is.array(message.params) && (type === void 0 || type.numberOfParams > 1)) {
notificationHandler ? notificationHandler(...message.params) : starNotificationHandler(message.method, ...message.params);
}
else {
notificationHandler ? notificationHandler(message.params) : starNotificationHandler(message.method, message.params);
}
}
catch (error) {
if (error.message) {
logger.error(`Notification handler '${message.method}' failed with message: ${error.message}`);
}
else {
logger.error(`Notification handler '${message.method}' failed unexpectedly.`);
}
}
}
else {
unhandledNotificationEmitter.fire(message);
}
}
function handleInvalidMessage(message) {
if (!message) {
logger.error('Received empty message.');
return;
}
logger.error(`Received message which is neither a response nor a notification message:\n${JSON.stringify(message, null, 4)}`);
// Test whether we find an id to reject the promise
let responseMessage = message;
if (Is.string(responseMessage.id) || Is.number(responseMessage.id)) {
let key = String(responseMessage.id);
let responseHandler = responsePromises[key];
if (responseHandler) {
responseHandler.reject(new Error('The received response has neither a result nor an error property.'));
}
}
}
function traceSendingRequest(message) {
if (trace === Trace.Off || !tracer) {
return;
}
if (traceFormat === TraceFormat.Text) {
let data = undefined;
if (trace === Trace.Verbose && message.params) {
data = `Params: ${JSON.stringify(message.params, null, 4)}\n\n`;
}
tracer.log(`Sending request '${message.method} - (${message.id})'.`, data);
}
else {
logLSPMessage('send-request', message);
}
}
function traceSendingNotification(message) {
if (trace === Trace.Off || !tracer) {
return;
}
if (traceFormat === TraceFormat.Text) {
let data = undefined;
if (trace === Trace.Verbose) {
if (message.params) {
data = `Params: ${JSON.stringify(message.params, null, 4)}\n\n`;
}
else {
data = 'No parameters provided.\n\n';
}
}
tracer.log(`Sending notification '${message.method}'.`, data);
}
else {
logLSPMessage('send-notification', message);
}
}
function traceSendingResponse(message, method, startTime) {
if (trace === Trace.Off || !tracer) {
return;
}
if (traceFormat === TraceFormat.Text) {
let data = undefined;
if (trace === Trace.Verbose) {
if (message.error && message.error.data) {
data = `Error data: ${JSON.stringify(message.error.data, null, 4)}\n\n`;
}
else {
if (message.result) {
data = `Result: ${JSON.stringify(message.result, null, 4)}\n\n`;
}
else if (message.error === void 0) {
data = 'No result returned.\n\n';
}
}
}
tracer.log(`Sending response '${method} - (${message.id})'. Processing request took ${Date.now() - startTime}ms`, data);
}
else {
logLSPMessage('send-response', message);
}
}
function traceReceivedRequest(message) {
if (trace === Trace.Off || !tracer) {
return;
}
if (traceFormat === TraceFormat.Text) {
let data = undefined;
if (trace === Trace.Verbose && message.params) {
data = `Params: ${JSON.stringify(message.params, null, 4)}\n\n`;
}
tracer.log(`Received request '${message.method} - (${message.id})'.`, data);
}
else {
logLSPMessage('receive-request', message);
}
}
function traceReceivedNotification(message) {
if (trace === Trace.Off || !tracer || message.method === LogTraceNotification.type.method) {
return;
}
if (traceFormat === TraceFormat.Text) {
let data = undefined;
if (trace === Trace.Verbose) {
if (message.params) {
data = `Params: ${JSON.stringify(message.params, null, 4)}\n\n`;
}
else {
data = 'No parameters provided.\n\n';
}
}
tracer.log(`Received notification '${message.method}'.`, data);
}
else {
logLSPMessage('receive-notification', message);
}
}
function traceReceivedResponse(message, responsePromise) {
if (trace === Trace.Off || !tracer) {
return;
}
if (traceFormat === TraceFormat.Text) {
let data = undefined;
if (trace === Trace.Verbose) {
if (message.error && message.error.data) {
data = `Error data: ${JSON.stringify(message.error.data, null, 4)}\n\n`;
}
else {
if (message.result) {
data = `Result: ${JSON.stringify(message.result, null, 4)}\n\n`;
}
else if (message.error === void 0) {
data = 'No result returned.\n\n';
}
}
}
if (responsePromise) {
let error = message.error ? ` Request failed: ${message.error.message} (${message.error.code}).` : '';
tracer.log(`Received response '${responsePromise.method} - (${message.id})' in ${Date.now() - responsePromise.timerStart}ms.${error}`, data);
}
else {
tracer.log(`Received response ${message.id} without active response promise.`, data);
}
}
else {
logLSPMessage('receive-response', message);
}
}
function logLSPMessage(type, message) {
if (!tracer || trace === Trace.Off) {
return;
}
const lspMessage = {
isLSPMessage: true,
type,
message,
timestamp: Date.now()
};
tracer.log(lspMessage);
}
function throwIfClosedOrDisposed() {
if (isClosed()) {
throw new ConnectionError(ConnectionErrors.Closed, 'Connection is closed.');
}
if (isDisposed()) {
throw new ConnectionError(ConnectionErrors.Disposed, 'Connection is disposed.');
}
}
function throwIfListening() {
if (isListening()) {
throw new ConnectionError(ConnectionErrors.AlreadyListening, 'Connection is already listening');
}
}
function throwIfNotListening() {
if (!isListening()) {
throw new Error('Call listen() first.');
}
}
function undefinedToNull(param) {
if (param === void 0) {
return null;
}
else {
return param;
}
}
function computeMessageParams(type, params) {
let result;
let numberOfParams = type.numberOfParams;
switch (numberOfParams) {
case 0:
result = null;
break;
case 1:
result = undefinedToNull(params[0]);
break;
default:
result = [];
for (let i = 0; i < params.length && i < numberOfParams; i++) {
result.push(undefinedToNull(params[i]));
}
if (params.length < numberOfParams) {
for (let i = params.length; i < numberOfParams; i++) {
result.push(null);
}
}
break;
}
return result;
}
let connection = {
sendNotification: (type, ...params) => {
throwIfClosedOrDisposed();
let method;
let messageParams;
if (Is.string(type)) {
method = type;
switch (params.length) {
case 0:
messageParams = null;
break;
case 1:
messageParams = params[0];
break;
default:
messageParams = params;
break;
}
}
else {
method = type.method;
messageParams = computeMessageParams(type, params);
}
let notificationMessage = {
jsonrpc: version,
method: method,
params: messageParams
};
traceSendingNotification(notificationMessage);
messageWriter.write(notificationMessage);
},
onNotification: (type, handler) => {
throwIfClosedOrDisposed();
if (Is.func(type)) {
starNotificationHandler = type;
}
else if (handler) {
if (Is.string(type)) {
notificationHandlers[type] = { type: undefined, handler };
}
else {
notificationHandlers[type.method] = { type, handler };
}
}
},
sendRequest: (type, ...params) => {
throwIfClosedOrDisposed();
throwIfNotListening();
let method;
let messageParams;
let token = undefined;
if (Is.string(type)) {
method = type;
switch (params.length) {
case 0:
messageParams = null;
break;
case 1:
// The cancellation token is optional so it can also be undefined.
if (cancellation_1.CancellationToken.is(params[0])) {
messageParams = null;
token = params[0];
}
else {
messageParams = undefinedToNull(params[0]);
}
break;
default:
const last = params.length - 1;
if (cancellation_1.CancellationToken.is(params[last])) {
token = params[last];
if (params.length === 2) {
messageParams = undefinedToNull(params[0]);
}
else {
messageParams = params.slice(0, last).map(value => undefinedToNull(value));
}
}
else {
messageParams = params.map(value => undefinedToNull(value));
}
break;
}
}
else {
method = type.method;
messageParams = computeMessageParams(type, params);
let numberOfParams = type.numberOfParams;
token = cancellation_1.CancellationToken.is(params[numberOfParams]) ? params[numberOfParams] : undefined;
}
let id = sequenceNumber++;
let result = new Promise((resolve, reject) => {
let requestMessage = {
jsonrpc: version,
id: id,
method: method,
params: messageParams
};
let responsePromise = { method: method, timerStart: Date.now(), resolve, reject };
traceSendingRequest(requestMessage);
try {
messageWriter.write(requestMessage);
}
catch (e) {
// Writing the message failed. So we need to reject the promise.
responsePromise.reject(new messages_1.ResponseError(messages_1.ErrorCodes.MessageWriteError, e.message ? e.message : 'Unknown reason'));
responsePromise = null;
}
if (responsePromise) {
responsePromises[String(id)] = responsePromise;
}
});
if (token) {
token.onCancellationRequested(() => {
connection.sendNotification(CancelNotification.type, { id });
});
}
return result;
},
onRequest: (type, handler) => {
throwIfClosedOrDisposed();
if (Is.func(type)) {
starRequestHandler = type;
}
else if (handler) {
if (Is.string(type)) {
requestHandlers[type] = { type: undefined, handler };
}
else {
requestHandlers[type.method] = { type, handler };
}
}
},
trace: (_value, _tracer, sendNotificationOrTraceOptions) => {
let _sendNotification = false;
let _traceFormat = TraceFormat.Text;
if (sendNotificationOrTraceOptions !== void 0) {
if (Is.boolean(sendNotificationOrTraceOptions)) {
_sendNotification = sendNotificationOrTraceOptions;
}
else {
_sendNotification = sendNotificationOrTraceOptions.sendNotification || false;
_traceFormat = sendNotificationOrTraceOptions.traceFormat || TraceFormat.Text;
}
}
trace = _value;
traceFormat = _traceFormat;
if (trace === Trace.Off) {
tracer = undefined;
}
else {
tracer = _tracer;
}
if (_sendNotification && !isClosed() && !isDisposed()) {
connection.sendNotification(SetTraceNotification.type, { value: Trace.toString(_value) });
}
},
onError: errorEmitter.event,
onClose: closeEmitter.event,
onUnhandledNotification: unhandledNotificationEmitter.event,
onDispose: disposeEmitter.event,
dispose: () => {
if (isDisposed()) {
return;
}
state = ConnectionState.Disposed;
disposeEmitter.fire(undefined);
let error = new Error('Connection got disposed.');
Object.keys(responsePromises).forEach((key) => {
responsePromises[key].reject(error);
});
responsePromises = Object.create(null);
requestTokens = Object.create(null);
messageQueue = new linkedMap_1.LinkedMap();
// Test for backwards compatibility
if (Is.func(messageWriter.dispose)) {
messageWriter.dispose();
}
if (Is.func(messageReader.dispose)) {
messageReader.dispose();
}
},
listen: () => {
throwIfClosedOrDisposed();
throwIfListening();
state = ConnectionState.Listening;
messageReader.listen(callback);
},
inspect: () => {
console.log("inspect");
}
};
connection.onNotification(LogTraceNotification.type, (params) => {
if (trace === Trace.Off || !tracer) {
return;
}
tracer.log(params.message, trace === Trace.Verbose ? params.verbose : undefined);
});
return connection;
}
function isMessageReader(value) {
return value.listen !== void 0 && value.read === void 0;
}
function isMessageWriter(value) {
return value.write !== void 0 && value.end === void 0;
}
function createMessageConnection(input, output, logger, strategy) {
if (!logger) {
logger = exports.NullLogger;
}
let reader = isMessageReader(input) ? input : new messageReader_1.StreamMessageReader(input);
let writer = isMessageWriter(output) ? output : new messageWriter_1.StreamMessageWriter(output);
return _createMessageConnection(reader, writer, logger, strategy);
}
exports.createMessageConnection = createMessageConnection;
/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
Object.defineProperty(exports, "__esModule", { value: true });
function boolean(value) {
return value === true || value === false;
}
exports.boolean = boolean;
function string(value) {
return typeof value === 'string' || value instanceof String;
}
exports.string = string;
function number(value) {
return typeof value === 'number' || value instanceof Number;
}
exports.number = number;
function error(value) {
return value instanceof Error;
}
exports.error = error;
function func(value) {
return typeof value === 'function';
}
exports.func = func;
function array(value) {
return Array.isArray(value);
}
exports.array = array;
function stringArray(value) {
return array(value) && value.every(elem => string(elem));
}
exports.stringArray = stringArray;
/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
Object.defineProperty(exports, "__esModule", { value: true });
const is = __webpack_require__(5);
/**
* Predefined error codes.
*/
var ErrorCodes;
(function (ErrorCodes) {
// Defined by JSON RPC
ErrorCodes.ParseError = -32700;
ErrorCodes.InvalidRequest = -32600;
ErrorCodes.MethodNotFound = -32601;
ErrorCodes.InvalidParams = -32602;
ErrorCodes.InternalError = -32603;
ErrorCodes.serverErrorStart = -32099;
ErrorCodes.serverErrorEnd = -32000;
ErrorCodes.ServerNotInitialized = -32002;
ErrorCodes.UnknownErrorCode = -32001;
// Defined by the protocol.
ErrorCodes.RequestCancelled = -32800;
ErrorCodes.ContentModified = -32801;
// Defined by VSCode library.
ErrorCodes.MessageWriteError = 1;
ErrorCodes.MessageReadError = 2;
})(ErrorCodes = exports.ErrorCodes || (exports.ErrorCodes = {}));
/**
* An error object return in a response in case a request
* has failed.
*/
class ResponseError extends Error {
constructor(code, message, data) {
super(message);
this.code = is.number(code) ? code : ErrorCodes.UnknownErrorCode;
this.data = data;
Object.setPrototypeOf(this, ResponseError.prototype);
}
toJson() {
return {
code: this.code,
message: this.message,
data: this.data,
};
}
}
exports.ResponseError = ResponseError;
/**
* An abstract implementation of a MessageType.
*/
class AbstractMessageType {
constructor(_method, _numberOfParams) {
this._method = _method;
this._numberOfParams = _numberOfParams;
}
get method() {
return this._method;
}
get numberOfParams() {
return this._numberOfParams;
}
}
exports.AbstractMessageType = AbstractMessageType;
/**
* Classes to type request response pairs
*/
class RequestType0 extends AbstractMessageType {
constructor(method) {
super(method, 0);
this._ = undefined;
}
}
exports.RequestType0 = RequestType0;
class RequestType extends AbstractMessageType {
constructor(method) {
super(method, 1);
this._ = undefined;
}
}
exports.RequestType = RequestType;
class RequestType1 extends AbstractMessageType {
constructor(method) {
super(method, 1);
this._ = undefined;
}
}
exports.RequestType1 = RequestType1;
class RequestType2 extends AbstractMessageType {
constructor(method) {
super(method, 2);
this._ = undefined;
}
}
exports.RequestType2 = RequestType2;
class RequestType3 extends AbstractMessageType {
constructor(method) {
super(method, 3);
this._ = undefined;
}
}
exports.RequestType3 = RequestType3;
class RequestType4 extends AbstractMessageType {
constructor(method) {
super(method, 4);
this._ = undefined;
}
}
exports.RequestType4 = RequestType4;
class RequestType5 extends AbstractMessageType {
constructor(method) {
super(method, 5);
this._ = undefined;
}
}
exports.RequestType5 = RequestType5;
class RequestType6 extends AbstractMessageType {
constructor(method) {
super(method, 6);
this._ = undefined;
}
}
exports.RequestType6 = RequestType6;
class RequestType7 extends AbstractMessageType {
constructor(method) {
super(method, 7);
this._ = undefined;
}
}
exports.RequestType7 = RequestType7;
class RequestType8 extends AbstractMessageType {
constructor(method) {
super(method, 8);
this._ = undefined;
}
}
exports.RequestType8 = RequestType8;
class RequestType9 extends AbstractMessageType {
constructor(method) {
super(method, 9);
this._ = undefined;
}
}
exports.RequestType9 = RequestType9;
class NotificationType extends AbstractMessageType {
constructor(method) {
super(method, 1);
this._ = undefined;
}
}
exports.NotificationType = NotificationType;
class NotificationType0 extends AbstractMessageType {
constructor(method) {
super(method, 0);
this._ = undefined;
}
}
exports.NotificationType0 = NotificationType0;
class NotificationType1 extends AbstractMessageType {
constructor(method) {
super(method, 1);
this._ = undefined;
}
}
exports.NotificationType1 = NotificationType1;
class NotificationType2 extends AbstractMessageType {
constructor(method) {
super(method, 2);
this._ = undefined;
}
}
exports.NotificationType2 = NotificationType2;
class NotificationType3 extends AbstractMessageType {
constructor(method) {
super(method, 3);
this._ = undefined;
}
}
exports.NotificationType3 = NotificationType3;
class NotificationType4 extends AbstractMessageType {
constructor(method) {
super(method, 4);
this._ = undefined;
}
}
exports.NotificationType4 = NotificationType4;
class NotificationType5 extends AbstractMessageType {
constructor(method) {
super(method, 5);
this._ = undefined;
}
}
exports.NotificationType5 = NotificationType5;
class NotificationType6 extends AbstractMessageType {
constructor(method) {
super(method, 6);
this._ = undefined;
}
}
exports.NotificationType6 = NotificationType6;
class NotificationType7 extends AbstractMessageType {
constructor(method) {
super(method, 7);
this._ = undefined;
}
}
exports.NotificationType7 = NotificationType7;
class NotificationType8 extends AbstractMessageType {
constructor(method) {
super(method, 8);
this._ = undefined;
}
}
exports.NotificationType8 = NotificationType8;
class NotificationType9 extends AbstractMessageType {
constructor(method) {
super(method, 9);
this._ = undefined;
}
}
exports.NotificationType9 = NotificationType9;
/**
* Tests if the given message is a request message
*/
function isRequestMessage(message) {
let candidate = message;
return candidate && is.string(candidate.method) && (is.string(candidate.id) || is.number(candidate.id));
}
exports.isRequestMessage = isRequestMessage;
/**
* Tests if the given message is a notification message
*/
function isNotificationMessage(message) {
let candidate = message;
return candidate && is.string(candidate.method) && message.id === void 0;
}
exports.isNotificationMessage = isNotificationMessage;
/**
* Tests if the given message is a response message
*/
function isResponseMessage(message) {
let candidate = message;
return candidate && (candidate.result !== void 0 || !!candidate.error) && (is.string(candidate.id) || is.number(candidate.id) || candidate.id === null);
}
exports.isResponseMessage = isResponseMessage;
/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = __webpack_require__(8);
const Is = __webpack_require__(5);
let DefaultSize = 8192;
let CR = Buffer.from('\r', 'ascii')[0];
let LF = Buffer.from('\n', 'ascii')[0];
let CRLF = '\r\n';
class MessageBuffer {
constructor(encoding = 'utf8') {
this.encoding = encoding;
this.index = 0;
this.buffer = Buffer.allocUnsafe(DefaultSize);
}
append(chunk) {
var toAppend = chunk;
if (typeof (chunk) === 'string') {
var str = chunk;
var bufferLen = Buffer.byteLength(str, this.encoding);
toAppend = Buffer.allocUnsafe(bufferLen);
toAppend.write(str, 0, bufferLen, this.encoding);
}
if (this.buffer.length - this.index >= toAppend.length) {
toAppend.copy(this.buffer, this.index, 0, toAppend.length);
}
else {
var newSize = (Math.ceil((this.index + toAppend.length) / DefaultSize) + 1) * DefaultSize;
if (this.index === 0) {
this.buffer = Buffer.allocUnsafe(newSize);
toAppend.copy(this.buffer, 0, 0, toAppend.length);
}
else {
this.buffer = Buffer.concat([this.buffer.slice(0, this.index), toAppend], newSize);
}
}
this.index += toAppend.length;
}
tryReadHeaders() {
let result = undefined;
let current = 0;
while (current + 3 < this.index && (this.buffer[current] !== CR || this.buffer[current + 1] !== LF || this.buffer[current + 2] !== CR || this.buffer[current + 3] !== LF)) {
current++;
}
// No header / body separator found (e.g CRLFCRLF)
if (current + 3 >= this.index) {
return result;
}
result = Object.create(null);
let headers = this.buffer.toString('ascii', 0, current).split(CRLF);
headers.forEach((header) => {
let index = header.indexOf(':');
if (index === -1) {
throw new Error('Message header must separate key and value using :');
}
let key = header.substr(0, index);
let value = header.substr(index + 1).trim();
result[key] = value;
});
let nextStart = current + 4;
this.buffer = this.buffer.slice(nextStart);
this.index = this.index - nextStart;
return result;
}
tryReadContent(length) {
if (this.index < length) {
return null;
}
let result = this.buffer.toString(this.encoding, 0, length);
let nextStart = length;
this.buffer.copy(this.buffer, 0, nextStart);
this.index = this.index - nextStart;
return result;
}
get numberOfBytes() {
return this.index;
}
}
var MessageReader;
(function (MessageReader) {
function is(value) {
let candidate = value;
return candidate && Is.func(candidate.listen) && Is.func(candidate.dispose) &&
Is.func(candidate.onError) && Is.func(candidate.onClose) && Is.func(candidate.onPartialMessage);
}
MessageReader.is = is;
})(MessageReader = exports.MessageReader || (exports.MessageReader = {}));
class AbstractMessageReader {
constructor() {
this.errorEmitter = new events_1.Emitter();
this.closeEmitter = new events_1.Emitter();
this.partialMessageEmitter = new events_1.Emitter();
}
dispose() {
this.errorEmitter.dispose();
this.closeEmitter.dispose();
}
get onError() {
return this.errorEmitter.event;
}
fireError(error) {
this.errorEmitter.fire(this.asError(error));
}
get onClose() {
return this.closeEmitter.event;
}
fireClose() {
this.closeEmitter.fire(undefined);
}
get onPartialMessage() {
return this.partialMessageEmitter.event;
}
firePartialMessage(info) {
this.partialMessageEmitter.fire(info);
}
asError(error) {
if (error instanceof Error) {
return error;
}
else {
return new Error(`Reader received error. Reason: ${Is.string(error.message) ? error.message : 'unknown'}`);
}
}
}
exports.AbstractMessageReader = AbstractMessageReader;
class StreamMessageReader extends AbstractMessageReader {
constructor(readable, encoding = 'utf8') {
super();
this.readable = readable;
this.buffer = new MessageBuffer(encoding);
this._partialMessageTimeout = 10000;
}
set partialMessageTimeout(timeout) {
this._partialMessageTimeout = timeout;
}
get partialMessageTimeout() {
return this._partialMessageTimeout;
}
listen(callback) {
this.nextMessageLength = -1;
this.messageToken = 0;
this.partialMessageTimer = undefined;
this.callback = callback;
this.readable.on('data', (data) => {
this.onData(data);
});
this.readable.on('error', (error) => this.fireError(error));
this.readable.on('close', () => this.fireClose());
}
onData(data) {
this.buffer.append(data);
while (true) {
if (this.nextMessageLength === -1) {
let headers = this.buffer.tryReadHeaders();
if (!headers) {
return;
}
let contentLength = headers['Content-Length'];
if (!contentLength) {
throw new Error('Header must provide a Content-Length property.');
}
let length = parseInt(contentLength);
if (isNaN(length)) {
throw new Error('Content-Length value must be a number.');
}
this.nextMessageLength = length;
// Take the encoding form the header. For compatibility
// treat both utf-8 and utf8 as node utf8
}
var msg = this.buffer.tryReadContent(this.nextMessageLength);
if (msg === null) {
/** We haven't received the full message yet. */
this.setPartialMessageTimer();
return;
}
this.clearPartialMessageTimer();
this.nextMessageLength = -1;
this.messageToken++;
var json = JSON.parse(msg);
this.callback(json);
}
}
clearPartialMessageTimer() {
if (this.partialMessageTimer) {
clearTimeout(this.partialMessageTimer);
this.partialMessageTimer = undefined;
}
}
setPartialMessageTimer() {
this.clearPartialMessageTimer();
if (this._partialMessageTimeout <= 0) {
return;
}
this.partialMessageTimer = setTimeout((token, timeout) => {
this.partialMessageTimer = undefined;
if (token === this.messageToken) {
this.firePartialMessage({ messageToken: token, waitingTime: timeout });
this.setPartialMessageTimer();
}
}, this._partialMessageTimeout, this.messageToken, this._partialMessageTimeout);
}
}
exports.StreamMessageReader = StreamMessageReader;
class IPCMessageReader extends AbstractMessageReader {
constructor(process) {
super();
this.process = process;
let eventEmitter = this.process;
eventEmitter.on('error', (error) => this.fireError(error));
eventEmitter.on('close', () => this.fireClose());
}
listen(callback) {
this.process.on('message', callback);
}
}
exports.IPCMessageReader = IPCMessageReader;
class SocketMessageReader extends StreamMessageReader {
constructor(socket, encoding = 'utf-8') {
super(socket, encoding);
}
}
exports.SocketMessageReader = SocketMessageReader;
/***/ }),
/* 8 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
Object.defineProperty(exports, "__esModule", { value: true });
var Disposable;
(function (Disposable) {
function create(func) {
return {
dispose: func
};
}
Disposable.create = create;
})(Disposable = exports.Disposable || (exports.Disposable = {}));
var Event;
(function (Event) {
const _disposable = { dispose() { } };
Event.None = function () { return _disposable; };
})(Event = exports.Event || (exports.Event = {}));
class CallbackList {
add(callback, context = null, bucket) {
if (!this._callbacks) {
this._callbacks = [];
this._contexts = [];
}
this._callbacks.push(callback);
this._contexts.push(context);
if (Array.isArray(bucket)) {
bucket.push({ dispose: () => this.remove(callback, context) });
}
}
remove(callback, context = null) {
if (!this._callbacks) {
return;
}
var foundCallbackWithDifferentContext = false;
for (var i = 0, len = this._callbacks.length; i < len; i++) {
if (this._callbacks[i] === callback) {
if (this._contexts[i] === context) {
// callback & context match => remove it
this._callbacks.splice(i, 1);
this._contexts.splice(i, 1);
return;
}
else {
foundCallbackWithDifferentContext = true;
}
}
}
if (foundCallbackWithDifferentContext) {
throw new Error('When adding a listener with a context, you should remove it with the same context');
}
}
invoke(...args) {
if (!this._callbacks) {
return [];
}
var ret = [], callbacks = this._callbacks.slice(0), contexts = this._contexts.slice(0);
for (var i = 0, len = callbacks.length; i < len; i++) {
try {
ret.push(callbacks[i].apply(contexts[i], args));
}
catch (e) {
console.error(e);
}
}
return ret;
}
isEmpty() {
return !this._callbacks || this._callbacks.length === 0;
}
dispose() {
this._callbacks = undefined;
this._contexts = undefined;
}
}
class Emitter {
constructor(_options) {
this._options = _options;
}
/**
* For the public to allow to subscribe
* to events from this Emitter
*/
get event() {
if (!this._event) {
this._event = (listener, thisArgs, disposables) => {
if (!this._callbacks) {
this._callbacks = new CallbackList();
}
if (this._options && this._options.onFirstListenerAdd && this._callbacks.isEmpty()) {
this._options.onFirstListenerAdd(this);
}
this._callbacks.add(listener, thisArgs);
let result;
result = {
dispose: () => {
this._callbacks.remove(listener, thisArgs);
result.dispose = Emitter._noop;
if (this._options && this._options.onLastListenerRemove && this._callbacks.isEmpty()) {
this._options.onLastListenerRemove(this);
}
}
};
if (Array.isArray(disposables)) {
disposables.push(result);
}
return result;
};
}
return this._event;
}
/**
* To be kept private to fire an event to
* subscribers
*/
fire(event) {
if (this._callbacks) {
this._callbacks.invoke.call(this._callbacks, event);
}
}
dispose() {
if (this._callbacks) {
this._callbacks.dispose();
this._callbacks = undefined;
}
}
}
Emitter._noop = function () { };
exports.Emitter = Emitter;
/***/ }),
/* 9 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = __webpack_require__(8);
const Is = __webpack_require__(5);
let ContentLength = 'Content-Length: ';
let CRLF = '\r\n';
var MessageWriter;
(function (MessageWriter) {
function is(value) {
let candidate = value;
return candidate && Is.func(candidate.dispose) && Is.func(candidate.onClose) &&
Is.func(candidate.onError) && Is.func(candidate.write);
}
MessageWriter.is = is;
})(MessageWriter = exports.MessageWriter || (exports.MessageWriter = {}));
class AbstractMessageWriter {
constructor() {
this.errorEmitter = new events_1.Emitter();
this.closeEmitter = new events_1.Emitter();
}
dispose() {
this.errorEmitter.dispose();
this.closeEmitter.dispose();
}
get onError() {
return this.errorEmitter.event;
}
fireError(error, message, count) {
this.errorEmitter.fire([this.asError(error), message, count]);
}
get onClose() {
return this.closeEmitter.event;
}
fireClose() {
this.closeEmitter.fire(undefined);
}
asError(error) {
if (error instanceof Error) {
return error;
}
else {
return new Error(`Writer received error. Reason: ${Is.string(error.message) ? error.message : 'unknown'}`);
}
}
}
exports.AbstractMessageWriter = AbstractMessageWriter;
class StreamMessageWriter extends AbstractMessageWriter {
constructor(writable, encoding = 'utf8') {
super();
this.writable = writable;
this.encoding = encoding;
this.errorCount = 0;
this.writable.on('error', (error) => this.fireError(error));
this.writable.on('close', () => this.fireClose());
}
write(msg) {
let json = JSON.stringify(msg);
let contentLength = Buffer.byteLength(json, this.encoding);
let headers = [
ContentLength, contentLength.toString(), CRLF,
CRLF
];
try {
// Header must be written in ASCII encoding
this.writable.write(headers.join(''), 'ascii');
// Now write the content. This can be written in any encoding
this.writable.write(json, this.encoding);
this.errorCount = 0;
}
catch (error) {
this.errorCount++;
this.fireError(error, msg, this.errorCount);
}
}
}
exports.StreamMessageWriter = StreamMessageWriter;
class IPCMessageWriter extends AbstractMessageWriter {
constructor(process) {
super();
this.process = process;
this.errorCount = 0;
this.queue = [];
this.sending = false;
let eventEmitter = this.process;
eventEmitter.on('error', (error) => this.fireError(error));
eventEmitter.on('close', () => this.fireClose);
}
write(msg) {
if (!this.sending && this.queue.length === 0) {
// See https://github.com/nodejs/node/issues/7657
this.doWriteMessage(msg);
}
else {
this.queue.push(msg);
}
}
doWriteMessage(msg) {
try {
if (this.process.send) {
this.sending = true;
this.process.send(msg, undefined, undefined, (error) => {
this.sending = false;
if (error) {
this.errorCount++;
this.fireError(error, msg, this.errorCount);
}
else {
this.errorCount = 0;
}
if (this.queue.length > 0) {
this.doWriteMessage(this.queue.shift());
}
});
}
}
catch (error) {
this.errorCount++;
this.fireError(error, msg, this.errorCount);
}
}
}
exports.IPCMessageWriter = IPCMessageWriter;
class SocketMessageWriter extends AbstractMessageWriter {
constructor(socket, encoding = 'utf8') {
super();
this.socket = socket;
this.queue = [];
this.sending = false;
this.encoding = encoding;
this.errorCount = 0;
this.socket.on('error', (error) => this.fireError(error));
this.socket.on('close', () => this.fireClose());
}
dispose() {
super.dispose();
this.socket.destroy();
}
write(msg) {
if (!this.sending && this.queue.length === 0) {
// See https://github.com/nodejs/node/issues/7657
this.doWriteMessage(msg);
}
else {
this.queue.push(msg);
}
}
doWriteMessage(msg) {
let json = JSON.stringify(msg);
let contentLength = Buffer.byteLength(json, this.encoding);
let headers = [
ContentLength, contentLength.toString(), CRLF,
CRLF
];
try {
// Header must be written in ASCII encoding
this.sending = true;
this.socket.write(headers.join(''), 'ascii', (error) => {
if (error) {
this.handleError(error, msg);
}
try {
// Now write the content. This can be written in any encoding
this.socket.write(json, this.encoding, (error) => {
this.sending = false;
if (error) {
this.handleError(error, msg);
}
else {
this.errorCount = 0;
}
if (this.queue.length > 0) {
this.doWriteMessage(this.queue.shift());
}
});
}
catch (error) {
this.handleError(error, msg);
}
});
}
catch (error) {
this.handleError(error, msg);
}
}
handleError(error, msg) {
this.errorCount++;
this.fireError(error, msg, this.errorCount);
}
}
exports.SocketMessageWriter = SocketMessageWriter;
/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = __webpack_require__(8);
const Is = __webpack_require__(5);
var CancellationToken;
(function (CancellationToken) {
CancellationToken.None = Object.freeze({
isCancellationRequested: false,
onCancellationRequested: events_1.Event.None
});
CancellationToken.Cancelled = Object.freeze({
isCancellationRequested: true,
onCancellationRequested: events_1.Event.None
});
function is(value) {
let candidate = value;
return candidate && (candidate === CancellationToken.None
|| candidate === CancellationToken.Cancelled
|| (Is.boolean(candidate.isCancellationRequested) && !!candidate.onCancellationRequested));
}
CancellationToken.is = is;
})(CancellationToken = exports.CancellationToken || (exports.CancellationToken = {}));
const shortcutEvent = Object.freeze(function (callback, context) {
let handle = setTimeout(callback.bind(context), 0);
return { dispose() { clearTimeout(handle); } };
});
class MutableToken {
constructor() {
this._isCancelled = false;
}
cancel() {
if (!this._isCancelled) {
this._isCancelled = true;
if (this._emitter) {
this._emitter.fire(undefined);
this.dispose();
}
}
}
get isCancellationRequested() {
return this._isCancelled;
}
get onCancellationRequested() {
if (this._isCancelled) {
return shortcutEvent;
}
if (!this._emitter) {
this._emitter = new events_1.Emitter();
}
return this._emitter.event;
}
dispose() {
if (this._emitter) {
this._emitter.dispose();
this._emitter = undefined;
}
}
}
class CancellationTokenSource {
get token() {
if (!this._token) {
// be lazy and create the token only when
// actually needed
this._token = new MutableToken();
}
return this._token;
}
cancel() {
if (!this._token) {
// save an object by returning the default
// cancelled token when cancellation happens
// before someone asks for the token
this._token = CancellationToken.Cancelled;
}
else {
this._token.cancel();
}
}
dispose() {
if (!this._token) {
// ensure to initialize with an empty token if we had none
this._token = CancellationToken.None;
}
else if (this._token instanceof MutableToken) {
// actually dispose
this._token.dispose();
}
}
}
exports.CancellationTokenSource = CancellationTokenSource;
/***/ }),
/* 11 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
var Touch;
(function (Touch) {
Touch.None = 0;
Touch.First = 1;
Touch.Last = 2;
})(Touch = exports.Touch || (exports.Touch = {}));
class LinkedMap {
constructor() {
this._map = new Map();
this._head = undefined;
this._tail = undefined;
this._size = 0;
}
clear() {
this._map.clear();
this._head = undefined;
this._tail = undefined;
this._size = 0;
}
isEmpty() {
return !this._head && !this._tail;
}
get size() {
return this._size;
}
has(key) {
return this._map.has(key);
}
get(key) {
const item = this._map.get(key);
if (!item) {
return undefined;
}
return item.value;
}
set(key, value, touch = Touch.None) {
let item = this._map.get(key);
if (item) {
item.value = value;
if (touch !== Touch.None) {
this.touch(item, touch);
}
}
else {
item = { key, value, next: undefined, previous: undefined };
switch (touch) {
case Touch.None:
this.addItemLast(item);
break;
case Touch.First:
this.addItemFirst(item);
break;
case Touch.Last:
this.addItemLast(item);
break;
default:
this.addItemLast(item);
break;
}
this._map.set(key, item);
this._size++;
}
}
delete(key) {
const item = this._map.get(key);
if (!item) {
return false;
}
this._map.delete(key);
this.removeItem(item);
this._size--;
return true;
}
shift() {
if (!this._head && !this._tail) {
return undefined;
}
if (!this._head || !this._tail) {
throw new Error('Invalid list');
}
const item = this._head;
this._map.delete(item.key);
this.removeItem(item);
this._size--;
return item.value;
}
forEach(callbackfn, thisArg) {
let current = this._head;
while (current) {
if (thisArg) {
callbackfn.bind(thisArg)(current.value, current.key, this);
}
else {
callbackfn(current.value, current.key, this);
}
current = current.next;
}
}
forEachReverse(callbackfn, thisArg) {
let current = this._tail;
while (current) {
if (thisArg) {
callbackfn.bind(thisArg)(current.value, current.key, this);
}
else {
callbackfn(current.value, current.key, this);
}
current = current.previous;
}
}
values() {
let result = [];
let current = this._head;
while (current) {
result.push(current.value);
current = current.next;
}
return result;
}
keys() {
let result = [];
let current = this._head;
while (current) {
result.push(current.key);
current = current.next;
}
return result;
}
/* JSON RPC run on es5 which has no Symbol.iterator
public keys(): IterableIterator<K> {
let current = this._head;
let iterator: IterableIterator<K> = {
[Symbol.iterator]() {
return iterator;
},
next():IteratorResult<K> {
if (current) {
let result = { value: current.key, done: false };
current = current.next;
return result;
} else {
return { value: undefined, done: true };
}
}
};
return iterator;
}
public values(): IterableIterator<V> {
let current = this._head;
let iterator: IterableIterator<V> = {
[Symbol.iterator]() {
return iterator;
},
next():IteratorResult<V> {
if (current) {
let result = { value: current.value, done: false };
current = current.next;
return result;
} else {
return { value: undefined, done: true };
}
}
};
return iterator;
}
*/
addItemFirst(item) {
// First time Insert
if (!this._head && !this._tail) {
this._tail = item;
}
else if (!this._head) {
throw new Error('Invalid list');
}
else {
item.next = this._head;
this._head.previous = item;
}
this._head = item;
}
addItemLast(item) {
// First time Insert
if (!this._head && !this._tail) {
this._head = item;
}
else if (!this._tail) {
throw new Error('Invalid list');
}
else {
item.previous = this._tail;
this._tail.next = item;
}
this._tail = item;
}
removeItem(item) {
if (item === this._head && item === this._tail) {
this._head = undefined;
this._tail = undefined;
}
else if (item === this._head) {
this._head = item.next;
}
else if (item === this._tail) {
this._tail = item.previous;
}
else {
const next = item.next;
const previous = item.previous;
if (!next || !previous) {
throw new Error('Invalid list');
}
next.previous = previous;
previous.next = next;
}
}
touch(item, touch) {
if (!this._head || !this._tail) {
throw new Error('Invalid list');
}
if ((touch !== Touch.First && touch !== Touch.Last)) {
return;
}
if (touch === Touch.First) {
if (item === this._head) {
return;
}
const next = item.next;
const previous = item.previous;
// Unlink the item
if (item === this._tail) {
// previous must be defined since item was not head but is tail
// So there are more than on item in the map
previous.next = undefined;
this._tail = previous;
}
else {
// Both next and previous are not undefined since item was neither head nor tail.
next.previous = previous;
previous.next = next;
}
// Insert the node at head
item.previous = undefined;
item.next = this._head;
this._head.previous = item;
this._head = item;
}
else if (touch === Touch.Last) {
if (item === this._tail) {
return;
}
const next = item.next;
const previous = item.previous;
// Unlink the item.
if (item === this._head) {
// next must be defined since item was not tail but is head
// So there are more than on item in the map
next.previous = undefined;
this._head = next;
}
else {
// Both next and previous are not undefined since item was neither head nor tail.
next.previous = previous;
previous.next = next;
}
item.next = undefined;
item.previous = this._tail;
this._tail.next = item;
this._tail = item;
}
}
}
exports.LinkedMap = LinkedMap;
/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = __webpack_require__(13);
const os_1 = __webpack_require__(14);
const crypto_1 = __webpack_require__(15);
const net_1 = __webpack_require__(16);
const messageReader_1 = __webpack_require__(7);
const messageWriter_1 = __webpack_require__(9);
function generateRandomPipeName() {
const randomSuffix = crypto_1.randomBytes(21).toString('hex');
if (process.platform === 'win32') {
return `\\\\.\\pipe\\vscode-jsonrpc-${randomSuffix}-sock`;
}
else {
// Mac/Unix: use socket file
return path_1.join(os_1.tmpdir(), `vscode-${randomSuffix}.sock`);
}
}
exports.generateRandomPipeName = generateRandomPipeName;
function createClientPipeTransport(pipeName, encoding = 'utf-8') {
let connectResolve;
let connected = new Promise((resolve, _reject) => {
connectResolve = resolve;
});
return new Promise((resolve, reject) => {
let server = net_1.createServer((socket) => {
server.close();
connectResolve([
new messageReader_1.SocketMessageReader(socket, encoding),
new messageWriter_1.SocketMessageWriter(socket, encoding)
]);
});
server.on('error', reject);
server.listen(pipeName, () => {
server.removeListener('error', reject);
resolve({
onConnected: () => { return connected; }
});
});
});
}
exports.createClientPipeTransport = createClientPipeTransport;
function createServerPipeTransport(pipeName, encoding = 'utf-8') {
const socket = net_1.createConnection(pipeName);
return [
new messageReader_1.SocketMessageReader(socket, encoding),
new messageWriter_1.SocketMessageWriter(socket, encoding)
];
}
exports.createServerPipeTransport = createServerPipeTransport;
/***/ }),
/* 13 */
/***/ (function(module, exports) {
module.exports = require("path");
/***/ }),
/* 14 */
/***/ (function(module, exports) {
module.exports = require("os");
/***/ }),
/* 15 */
/***/ (function(module, exports) {
module.exports = require("crypto");
/***/ }),
/* 16 */
/***/ (function(module, exports) {
module.exports = require("net");
/***/ }),
/* 17 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
Object.defineProperty(exports, "__esModule", { value: true });
const net_1 = __webpack_require__(16);
const messageReader_1 = __webpack_require__(7);
const messageWriter_1 = __webpack_require__(9);
function createClientSocketTransport(port, encoding = 'utf-8') {
let connectResolve;
let connected = new Promise((resolve, _reject) => {
connectResolve = resolve;
});
return new Promise((resolve, reject) => {
let server = net_1.createServer((socket) => {
server.close();
connectResolve([
new messageReader_1.SocketMessageReader(socket, encoding),
new messageWriter_1.SocketMessageWriter(socket, encoding)
]);
});
server.on('error', reject);
server.listen(port, '127.0.0.1', () => {
server.removeListener('error', reject);
resolve({
onConnected: () => { return connected; }
});
});
});
}
exports.createClientSocketTransport = createClientSocketTransport;
function createServerSocketTransport(port, encoding = 'utf-8') {
const socket = net_1.createConnection(port, '127.0.0.1');
return [
new messageReader_1.SocketMessageReader(socket, encoding),
new messageWriter_1.SocketMessageWriter(socket, encoding)
];
}
exports.createServerSocketTransport = createServerSocketTransport;
/***/ }),
/* 18 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Position", function() { return Position; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Range", function() { return Range; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Location", function() { return Location; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LocationLink", function() { return LocationLink; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Color", function() { return Color; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ColorInformation", function() { return ColorInformation; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ColorPresentation", function() { return ColorPresentation; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FoldingRangeKind", function() { return FoldingRangeKind; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FoldingRange", function() { return FoldingRange; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DiagnosticRelatedInformation", function() { return DiagnosticRelatedInformation; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DiagnosticSeverity", function() { return DiagnosticSeverity; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DiagnosticTag", function() { return DiagnosticTag; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Diagnostic", function() { return Diagnostic; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Command", function() { return Command; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextEdit", function() { return TextEdit; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextDocumentEdit", function() { return TextDocumentEdit; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CreateFile", function() { return CreateFile; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RenameFile", function() { return RenameFile; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DeleteFile", function() { return DeleteFile; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WorkspaceEdit", function() { return WorkspaceEdit; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WorkspaceChange", function() { return WorkspaceChange; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextDocumentIdentifier", function() { return TextDocumentIdentifier; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VersionedTextDocumentIdentifier", function() { return VersionedTextDocumentIdentifier; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextDocumentItem", function() { return TextDocumentItem; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MarkupKind", function() { return MarkupKind; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MarkupContent", function() { return MarkupContent; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CompletionItemKind", function() { return CompletionItemKind; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InsertTextFormat", function() { return InsertTextFormat; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CompletionItem", function() { return CompletionItem; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CompletionList", function() { return CompletionList; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MarkedString", function() { return MarkedString; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Hover", function() { return Hover; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ParameterInformation", function() { return ParameterInformation; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SignatureInformation", function() { return SignatureInformation; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DocumentHighlightKind", function() { return DocumentHighlightKind; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DocumentHighlight", function() { return DocumentHighlight; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SymbolKind", function() { return SymbolKind; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SymbolInformation", function() { return SymbolInformation; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DocumentSymbol", function() { return DocumentSymbol; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CodeActionKind", function() { return CodeActionKind; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CodeActionContext", function() { return CodeActionContext; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CodeAction", function() { return CodeAction; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CodeLens", function() { return CodeLens; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FormattingOptions", function() { return FormattingOptions; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DocumentLink", function() { return DocumentLink; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EOL", function() { return EOL; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextDocument", function() { return TextDocument; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextDocumentSaveReason", function() { return TextDocumentSaveReason; });
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
/**
* The Position namespace provides helper functions to work with
* [Position](#Position) literals.
*/
var Position;
(function (Position) {
/**
* Creates a new Position literal from the given line and character.
* @param line The position's line.
* @param character The position's character.
*/
function create(line, character) {
return { line: line, character: character };
}
Position.create = create;
/**
* Checks whether the given liternal conforms to the [Position](#Position) interface.
*/
function is(value) {
var candidate = value;
return Is.objectLiteral(candidate) && Is.number(candidate.line) && Is.number(candidate.character);
}
Position.is = is;
})(Position || (Position = {}));
/**
* The Range namespace provides helper functions to work with
* [Range](#Range) literals.
*/
var Range;
(function (Range) {
function create(one, two, three, four) {
if (Is.number(one) && Is.number(two) && Is.number(three) && Is.number(four)) {
return { start: Position.create(one, two), end: Position.create(three, four) };
}
else if (Position.is(one) && Position.is(two)) {
return { start: one, end: two };
}
else {
throw new Error("Range#create called with invalid arguments[" + one + ", " + two + ", " + three + ", " + four + "]");
}
}
Range.create = create;
/**
* Checks whether the given literal conforms to the [Range](#Range) interface.
*/
function is(value) {
var candidate = value;
return Is.objectLiteral(candidate) && Position.is(candidate.start) && Position.is(candidate.end);
}
Range.is = is;
})(Range || (Range = {}));
/**
* The Location namespace provides helper functions to work with
* [Location](#Location) literals.
*/
var Location;
(function (Location) {
/**
* Creates a Location literal.
* @param uri The location's uri.
* @param range The location's range.
*/
function create(uri, range) {
return { uri: uri, range: range };
}
Location.create = create;
/**
* Checks whether the given literal conforms to the [Location](#Location) interface.
*/
function is(value) {
var candidate = value;
return Is.defined(candidate) && Range.is(candidate.range) && (Is.string(candidate.uri) || Is.undefined(candidate.uri));
}
Location.is = is;
})(Location || (Location = {}));
/**
* The LocationLink namespace provides helper functions to work with
* [LocationLink](#LocationLink) literals.
*/
var LocationLink;
(function (LocationLink) {
/**
* Creates a LocationLink literal.
* @param targetUri The definition's uri.
* @param targetRange The full range of the definition.
* @param targetSelectionRange The span of the symbol definition at the target.
* @param originSelectionRange The span of the symbol being defined in the originating source file.
*/
function create(targetUri, targetRange, targetSelectionRange, originSelectionRange) {
return { targetUri: targetUri, targetRange: targetRange, targetSelectionRange: targetSelectionRange, originSelectionRange: originSelectionRange };
}
LocationLink.create = create;
/**
* Checks whether the given literal conforms to the [LocationLink](#LocationLink) interface.
*/
function is(value) {
var candidate = value;
return Is.defined(candidate) && Range.is(candidate.targetRange) && Is.string(candidate.targetUri)
&& (Range.is(candidate.targetSelectionRange) || Is.undefined(candidate.targetSelectionRange))
&& (Range.is(candidate.originSelectionRange) || Is.undefined(candidate.originSelectionRange));
}
LocationLink.is = is;
})(LocationLink || (LocationLink = {}));
/**
* The Color namespace provides helper functions to work with
* [Color](#Color) literals.
*/
var Color;
(function (Color) {
/**
* Creates a new Color literal.
*/
function create(red, green, blue, alpha) {
return {
red: red,
green: green,
blue: blue,
alpha: alpha,
};
}
Color.create = create;
/**
* Checks whether the given literal conforms to the [Color](#Color) interface.
*/
function is(value) {
var candidate = value;
return Is.number(candidate.red)
&& Is.number(candidate.green)
&& Is.number(candidate.blue)
&& Is.number(candidate.alpha);
}
Color.is = is;
})(Color || (Color = {}));
/**
* The ColorInformation namespace provides helper functions to work with
* [ColorInformation](#ColorInformation) literals.
*/
var ColorInformation;
(function (ColorInformation) {
/**
* Creates a new ColorInformation literal.
*/
function create(range, color) {
return {
range: range,
color: color,
};
}
ColorInformation.create = create;
/**
* Checks whether the given literal conforms to the [ColorInformation](#ColorInformation) interface.
*/
function is(value) {
var candidate = value;
return Range.is(candidate.range) && Color.is(candidate.color);
}
ColorInformation.is = is;
})(ColorInformation || (ColorInformation = {}));
/**
* The Color namespace provides helper functions to work with
* [ColorPresentation](#ColorPresentation) literals.
*/
var ColorPresentation;
(function (ColorPresentation) {
/**
* Creates a new ColorInformation literal.
*/
function create(label, textEdit, additionalTextEdits) {
return {
label: label,
textEdit: textEdit,
additionalTextEdits: additionalTextEdits,
};
}
ColorPresentation.create = create;
/**
* Checks whether the given literal conforms to the [ColorInformation](#ColorInformation) interface.
*/
function is(value) {
var candidate = value;
return Is.string(candidate.label)
&& (Is.undefined(candidate.textEdit) || TextEdit.is(candidate))
&& (Is.undefined(candidate.additionalTextEdits) || Is.typedArray(candidate.additionalTextEdits, TextEdit.is));
}
ColorPresentation.is = is;
})(ColorPresentation || (ColorPresentation = {}));
/**
* Enum of known range kinds
*/
var FoldingRangeKind;
(function (FoldingRangeKind) {
/**
* Folding range for a comment
*/
FoldingRangeKind["Comment"] = "comment";
/**
* Folding range for a imports or includes
*/
FoldingRangeKind["Imports"] = "imports";
/**
* Folding range for a region (e.g. `#region`)
*/
FoldingRangeKind["Region"] = "region";
})(FoldingRangeKind || (FoldingRangeKind = {}));
/**
* The folding range namespace provides helper functions to work with
* [FoldingRange](#FoldingRange) literals.
*/
var FoldingRange;
(function (FoldingRange) {
/**
* Creates a new FoldingRange literal.
*/
function create(startLine, endLine, startCharacter, endCharacter, kind) {
var result = {
startLine: startLine,
endLine: endLine
};
if (Is.defined(startCharacter)) {
result.startCharacter = startCharacter;
}
if (Is.defined(endCharacter)) {
result.endCharacter = endCharacter;
}
if (Is.defined(kind)) {
result.kind = kind;
}
return result;
}
FoldingRange.create = create;
/**
* Checks whether the given literal conforms to the [FoldingRange](#FoldingRange) interface.
*/
function is(value) {
var candidate = value;
return Is.number(candidate.startLine) && Is.number(candidate.startLine)
&& (Is.undefined(candidate.startCharacter) || Is.number(candidate.startCharacter))
&& (Is.undefined(candidate.endCharacter) || Is.number(candidate.endCharacter))
&& (Is.undefined(candidate.kind) || Is.string(candidate.kind));
}
FoldingRange.is = is;
})(FoldingRange || (FoldingRange = {}));
/**
* The DiagnosticRelatedInformation namespace provides helper functions to work with
* [DiagnosticRelatedInformation](#DiagnosticRelatedInformation) literals.
*/
var DiagnosticRelatedInformation;
(function (DiagnosticRelatedInformation) {
/**
* Creates a new DiagnosticRelatedInformation literal.
*/
function create(location, message) {
return {
location: location,
message: message
};
}
DiagnosticRelatedInformation.create = create;
/**
* Checks whether the given literal conforms to the [DiagnosticRelatedInformation](#DiagnosticRelatedInformation) interface.
*/
function is(value) {
var candidate = value;
return Is.defined(candidate) && Location.is(candidate.location) && Is.string(candidate.message);
}
DiagnosticRelatedInformation.is = is;
})(DiagnosticRelatedInformation || (DiagnosticRelatedInformation = {}));
/**
* The diagnostic's severity.
*/
var DiagnosticSeverity;
(function (DiagnosticSeverity) {
/**
* Reports an error.
*/
DiagnosticSeverity.Error = 1;
/**
* Reports a warning.
*/
DiagnosticSeverity.Warning = 2;
/**
* Reports an information.
*/
DiagnosticSeverity.Information = 3;
/**
* Reports a hint.
*/
DiagnosticSeverity.Hint = 4;
})(DiagnosticSeverity || (DiagnosticSeverity = {}));
var DiagnosticTag;
(function (DiagnosticTag) {
/**
* Unused or unnecessary code.
*
* Clients are allowed to render diagnostics with this tag faded out instead of having
* an error squiggle.
*/
DiagnosticTag.Unnecessary = 1;
})(DiagnosticTag || (DiagnosticTag = {}));
/**
* The Diagnostic namespace provides helper functions to work with
* [Diagnostic](#Diagnostic) literals.
*/
var Diagnostic;
(function (Diagnostic) {
/**
* Creates a new Diagnostic literal.
*/
function create(range, message, severity, code, source, relatedInformation) {
var result = { range: range, message: message };
if (Is.defined(severity)) {
result.severity = severity;
}
if (Is.defined(code)) {
result.code = code;
}
if (Is.defined(source)) {
result.source = source;
}
if (Is.defined(relatedInformation)) {
result.relatedInformation = relatedInformation;
}
return result;
}
Diagnostic.create = create;
/**
* Checks whether the given literal conforms to the [Diagnostic](#Diagnostic) interface.
*/
function is(value) {
var candidate = value;
return Is.defined(candidate)
&& Range.is(candidate.range)
&& Is.string(candidate.message)
&& (Is.number(candidate.severity) || Is.undefined(candidate.severity))
&& (Is.number(candidate.code) || Is.string(candidate.code) || Is.undefined(candidate.code))
&& (Is.string(candidate.source) || Is.undefined(candidate.source))
&& (Is.undefined(candidate.relatedInformation) || Is.typedArray(candidate.relatedInformation, DiagnosticRelatedInformation.is));
}
Diagnostic.is = is;
})(Diagnostic || (Diagnostic = {}));
/**
* The Command namespace provides helper functions to work with
* [Command](#Command) literals.
*/
var Command;
(function (Command) {
/**
* Creates a new Command literal.
*/
function create(title, command) {
var args = [];
for (var _i = 2; _i < arguments.length; _i++) {
args[_i - 2] = arguments[_i];
}
var result = { title: title, command: command };
if (Is.defined(args) && args.length > 0) {
result.arguments = args;
}
return result;
}
Command.create = create;
/**
* Checks whether the given literal conforms to the [Command](#Command) interface.
*/
function is(value) {
var candidate = value;
return Is.defined(candidate) && Is.string(candidate.title) && Is.string(candidate.command);
}
Command.is = is;
})(Command || (Command = {}));
/**
* The TextEdit namespace provides helper function to create replace,
* insert and delete edits more easily.
*/
var TextEdit;
(function (TextEdit) {
/**
* Creates a replace text edit.
* @param range The range of text to be replaced.
* @param newText The new text.
*/
function replace(range, newText) {
return { range: range, newText: newText };
}
TextEdit.replace = replace;
/**
* Creates a insert text edit.
* @param position The position to insert the text at.
* @param newText The text to be inserted.
*/
function insert(position, newText) {
return { range: { start: position, end: position }, newText: newText };
}
TextEdit.insert = insert;
/**
* Creates a delete text edit.
* @param range The range of text to be deleted.
*/
function del(range) {
return { range: range, newText: '' };
}
TextEdit.del = del;
function is(value) {
var candidate = value;
return Is.objectLiteral(candidate)
&& Is.string(candidate.newText)
&& Range.is(candidate.range);
}
TextEdit.is = is;
})(TextEdit || (TextEdit = {}));
/**
* The TextDocumentEdit namespace provides helper function to create
* an edit that manipulates a text document.
*/
var TextDocumentEdit;
(function (TextDocumentEdit) {
/**
* Creates a new `TextDocumentEdit`
*/
function create(textDocument, edits) {
return { textDocument: textDocument, edits: edits };
}
TextDocumentEdit.create = create;
function is(value) {
var candidate = value;
return Is.defined(candidate)
&& VersionedTextDocumentIdentifier.is(candidate.textDocument)
&& Array.isArray(candidate.edits);
}
TextDocumentEdit.is = is;
})(TextDocumentEdit || (TextDocumentEdit = {}));
var CreateFile;
(function (CreateFile) {
function create(uri, options) {
var result = {
kind: 'create',
uri: uri
};
if (options !== void 0 && (options.overwrite !== void 0 || options.ignoreIfExists !== void 0)) {
result.options = options;
}
return result;
}
CreateFile.create = create;
function is(value) {
var candidate = value;
return candidate && candidate.kind === 'create' && Is.string(candidate.uri) &&
(candidate.options === void 0 ||
((candidate.options.overwrite === void 0 || Is.boolean(candidate.options.overwrite)) && (candidate.options.ignoreIfExists === void 0 || Is.boolean(candidate.options.ignoreIfExists))));
}
CreateFile.is = is;
})(CreateFile || (CreateFile = {}));
var RenameFile;
(function (RenameFile) {
function create(oldUri, newUri, options) {
var result = {
kind: 'rename',
oldUri: oldUri,
newUri: newUri
};
if (options !== void 0 && (options.overwrite !== void 0 || options.ignoreIfExists !== void 0)) {
result.options = options;
}
return result;
}
RenameFile.create = create;
function is(value) {
var candidate = value;
return candidate && candidate.kind === 'rename' && Is.string(candidate.oldUri) && Is.string(candidate.newUri) &&
(candidate.options === void 0 ||
((candidate.options.overwrite === void 0 || Is.boolean(candidate.options.overwrite)) && (candidate.options.ignoreIfExists === void 0 || Is.boolean(candidate.options.ignoreIfExists))));
}
RenameFile.is = is;
})(RenameFile || (RenameFile = {}));
var DeleteFile;
(function (DeleteFile) {
function create(uri, options) {
var result = {
kind: 'delete',
uri: uri
};
if (options !== void 0 && (options.recursive !== void 0 || options.ignoreIfNotExists !== void 0)) {
result.options = options;
}
return result;
}
DeleteFile.create = create;
function is(value) {
var candidate = value;
return candidate && candidate.kind === 'delete' && Is.string(candidate.uri) &&
(candidate.options === void 0 ||
((candidate.options.recursive === void 0 || Is.boolean(candidate.options.recursive)) && (candidate.options.ignoreIfNotExists === void 0 || Is.boolean(candidate.options.ignoreIfNotExists))));
}
DeleteFile.is = is;
})(DeleteFile || (DeleteFile = {}));
var WorkspaceEdit;
(function (WorkspaceEdit) {
function is(value) {
var candidate = value;
return candidate &&
(candidate.changes !== void 0 || candidate.documentChanges !== void 0) &&
(candidate.documentChanges === void 0 || candidate.documentChanges.every(function (change) {
if (Is.string(change.kind)) {
return CreateFile.is(change) || RenameFile.is(change) || DeleteFile.is(change);
}
else {
return TextDocumentEdit.is(change);
}
}));
}
WorkspaceEdit.is = is;
})(WorkspaceEdit || (WorkspaceEdit = {}));
var TextEditChangeImpl = /** @class */ (function () {
function TextEditChangeImpl(edits) {
this.edits = edits;
}
TextEditChangeImpl.prototype.insert = function (position, newText) {
this.edits.push(TextEdit.insert(position, newText));
};
TextEditChangeImpl.prototype.replace = function (range, newText) {
this.edits.push(TextEdit.replace(range, newText));
};
TextEditChangeImpl.prototype.delete = function (range) {
this.edits.push(TextEdit.del(range));
};
TextEditChangeImpl.prototype.add = function (edit) {
this.edits.push(edit);
};
TextEditChangeImpl.prototype.all = function () {
return this.edits;
};
TextEditChangeImpl.prototype.clear = function () {
this.edits.splice(0, this.edits.length);
};
return TextEditChangeImpl;
}());
/**
* A workspace change helps constructing changes to a workspace.
*/
var WorkspaceChange = /** @class */ (function () {
function WorkspaceChange(workspaceEdit) {
var _this = this;
this._textEditChanges = Object.create(null);
if (workspaceEdit) {
this._workspaceEdit = workspaceEdit;
if (workspaceEdit.documentChanges) {
workspaceEdit.documentChanges.forEach(function (change) {
if (TextDocumentEdit.is(change)) {
var textEditChange = new TextEditChangeImpl(change.edits);
_this._textEditChanges[change.textDocument.uri] = textEditChange;
}
});
}
else if (workspaceEdit.changes) {
Object.keys(workspaceEdit.changes).forEach(function (key) {
var textEditChange = new TextEditChangeImpl(workspaceEdit.changes[key]);
_this._textEditChanges[key] = textEditChange;
});
}
}
}
Object.defineProperty(WorkspaceChange.prototype, "edit", {
/**
* Returns the underlying [WorkspaceEdit](#WorkspaceEdit) literal
* use to be returned from a workspace edit operation like rename.
*/
get: function () {
return this._workspaceEdit;
},
enumerable: true,
configurable: true
});
WorkspaceChange.prototype.getTextEditChange = function (key) {
if (VersionedTextDocumentIdentifier.is(key)) {
if (!this._workspaceEdit) {
this._workspaceEdit = {
documentChanges: []
};
}
if (!this._workspaceEdit.documentChanges) {
throw new Error('Workspace edit is not configured for document changes.');
}
var textDocument = key;
var result = this._textEditChanges[textDocument.uri];
if (!result) {
var edits = [];
var textDocumentEdit = {
textDocument: textDocument,
edits: edits
};
this._workspaceEdit.documentChanges.push(textDocumentEdit);
result = new TextEditChangeImpl(edits);
this._textEditChanges[textDocument.uri] = result;
}
return result;
}
else {
if (!this._workspaceEdit) {
this._workspaceEdit = {
changes: Object.create(null)
};
}
if (!this._workspaceEdit.changes) {
throw new Error('Workspace edit is not configured for normal text edit changes.');
}
var result = this._textEditChanges[key];
if (!result) {
var edits = [];
this._workspaceEdit.changes[key] = edits;
result = new TextEditChangeImpl(edits);
this._textEditChanges[key] = result;
}
return result;
}
};
WorkspaceChange.prototype.createFile = function (uri, options) {
this.checkDocumentChanges();
this._workspaceEdit.documentChanges.push(CreateFile.create(uri, options));
};
WorkspaceChange.prototype.renameFile = function (oldUri, newUri, options) {
this.checkDocumentChanges();
this._workspaceEdit.documentChanges.push(RenameFile.create(oldUri, newUri, options));
};
WorkspaceChange.prototype.deleteFile = function (uri, options) {
this.checkDocumentChanges();
this._workspaceEdit.documentChanges.push(DeleteFile.create(uri, options));
};
WorkspaceChange.prototype.checkDocumentChanges = function () {
if (!this._workspaceEdit || !this._workspaceEdit.documentChanges) {
throw new Error('Workspace edit is not configured for document changes.');
}
};
return WorkspaceChange;
}());
/**
* The TextDocumentIdentifier namespace provides helper functions to work with
* [TextDocumentIdentifier](#TextDocumentIdentifier) literals.
*/
var TextDocumentIdentifier;
(function (TextDocumentIdentifier) {
/**
* Creates a new TextDocumentIdentifier literal.
* @param uri The document's uri.
*/
function create(uri) {
return { uri: uri };
}
TextDocumentIdentifier.create = create;
/**
* Checks whether the given literal conforms to the [TextDocumentIdentifier](#TextDocumentIdentifier) interface.
*/
function is(value) {
var candidate = value;
return Is.defined(candidate) && Is.string(candidate.uri);
}
TextDocumentIdentifier.is = is;
})(TextDocumentIdentifier || (TextDocumentIdentifier = {}));
/**
* The VersionedTextDocumentIdentifier namespace provides helper functions to work with
* [VersionedTextDocumentIdentifier](#VersionedTextDocumentIdentifier) literals.
*/
var VersionedTextDocumentIdentifier;
(function (VersionedTextDocumentIdentifier) {
/**
* Creates a new VersionedTextDocumentIdentifier literal.
* @param uri The document's uri.
* @param uri The document's text.
*/
function create(uri, version) {
return { uri: uri, version: version };
}
VersionedTextDocumentIdentifier.create = create;
/**
* Checks whether the given literal conforms to the [VersionedTextDocumentIdentifier](#VersionedTextDocumentIdentifier) interface.
*/
function is(value) {
var candidate = value;
return Is.defined(candidate) && Is.string(candidate.uri) && (candidate.version === null || Is.number(candidate.version));
}
VersionedTextDocumentIdentifier.is = is;
})(VersionedTextDocumentIdentifier || (VersionedTextDocumentIdentifier = {}));
/**
* The TextDocumentItem namespace provides helper functions to work with
* [TextDocumentItem](#TextDocumentItem) literals.
*/
var TextDocumentItem;
(function (TextDocumentItem) {
/**
* Creates a new TextDocumentItem literal.
* @param uri The document's uri.
* @param languageId The document's language identifier.
* @param version The document's version number.
* @param text The document's text.
*/
function create(uri, languageId, version, text) {
return { uri: uri, languageId: languageId, version: version, text: text };
}
TextDocumentItem.create = create;
/**
* Checks whether the given literal conforms to the [TextDocumentItem](#TextDocumentItem) interface.
*/
function is(value) {
var candidate = value;
return Is.defined(candidate) && Is.string(candidate.uri) && Is.string(candidate.languageId) && Is.number(candidate.version) && Is.string(candidate.text);
}
TextDocumentItem.is = is;
})(TextDocumentItem || (TextDocumentItem = {}));
/**
* Describes the content type that a client supports in various
* result literals like `Hover`, `ParameterInfo` or `CompletionItem`.
*
* Please note that `MarkupKinds` must not start with a `$`. This kinds
* are reserved for internal usage.
*/
var MarkupKind;
(function (MarkupKind) {
/**
* Plain text is supported as a content format
*/
MarkupKind.PlainText = 'plaintext';
/**
* Markdown is supported as a content format
*/
MarkupKind.Markdown = 'markdown';
})(MarkupKind || (MarkupKind = {}));
(function (MarkupKind) {
/**
* Checks whether the given value is a value of the [MarkupKind](#MarkupKind) type.
*/
function is(value) {
var candidate = value;
return candidate === MarkupKind.PlainText || candidate === MarkupKind.Markdown;
}
MarkupKind.is = is;
})(MarkupKind || (MarkupKind = {}));
var MarkupContent;
(function (MarkupContent) {
/**
* Checks whether the given value conforms to the [MarkupContent](#MarkupContent) interface.
*/
function is(value) {
var candidate = value;
return Is.objectLiteral(value) && MarkupKind.is(candidate.kind) && Is.string(candidate.value);
}
MarkupContent.is = is;
})(MarkupContent || (MarkupContent = {}));
/**
* The kind of a completion entry.
*/
var CompletionItemKind;
(function (CompletionItemKind) {
CompletionItemKind.Text = 1;
CompletionItemKind.Method = 2;
CompletionItemKind.Function = 3;
CompletionItemKind.Constructor = 4;
CompletionItemKind.Field = 5;
CompletionItemKind.Variable = 6;
CompletionItemKind.Class = 7;
CompletionItemKind.Interface = 8;
CompletionItemKind.Module = 9;
CompletionItemKind.Property = 10;
CompletionItemKind.Unit = 11;
CompletionItemKind.Value = 12;
CompletionItemKind.Enum = 13;
CompletionItemKind.Keyword = 14;
CompletionItemKind.Snippet = 15;
CompletionItemKind.Color = 16;
CompletionItemKind.File = 17;
CompletionItemKind.Reference = 18;
CompletionItemKind.Folder = 19;
CompletionItemKind.EnumMember = 20;
CompletionItemKind.Constant = 21;
CompletionItemKind.Struct = 22;
CompletionItemKind.Event = 23;
CompletionItemKind.Operator = 24;
CompletionItemKind.TypeParameter = 25;
})(CompletionItemKind || (CompletionItemKind = {}));
/**
* Defines whether the insert text in a completion item should be interpreted as
* plain text or a snippet.
*/
var InsertTextFormat;
(function (InsertTextFormat) {
/**
* The primary text to be inserted is treated as a plain string.
*/
InsertTextFormat.PlainText = 1;
/**
* The primary text to be inserted is treated as a snippet.
*
* A snippet can define tab stops and placeholders with `$1`, `$2`
* and `${3:foo}`. `$0` defines the final tab stop, it defaults to
* the end of the snippet. Placeholders with equal identifiers are linked,
* that is typing in one will update others too.
*
* See also: https://github.com/Microsoft/vscode/blob/master/src/vs/editor/contrib/snippet/common/snippet.md
*/
InsertTextFormat.Snippet = 2;
})(InsertTextFormat || (InsertTextFormat = {}));
/**
* The CompletionItem namespace provides functions to deal with
* completion items.
*/
var CompletionItem;
(function (CompletionItem) {
/**
* Create a completion item and seed it with a label.
* @param label The completion item's label
*/
function create(label) {
return { label: label };
}
CompletionItem.create = create;
})(CompletionItem || (CompletionItem = {}));
/**
* The CompletionList namespace provides functions to deal with
* completion lists.
*/
var CompletionList;
(function (CompletionList) {
/**
* Creates a new completion list.
*
* @param items The completion items.
* @param isIncomplete The list is not complete.
*/
function create(items, isIncomplete) {
return { items: items ? items : [], isIncomplete: !!isIncomplete };
}
CompletionList.create = create;
})(CompletionList || (CompletionList = {}));
var MarkedString;
(function (MarkedString) {
/**
* Creates a marked string from plain text.
*
* @param plainText The plain text.
*/
function fromPlainText(plainText) {
return plainText.replace(/[\\`*_{}[\]()#+\-.!]/g, "\\$&"); // escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash
}
MarkedString.fromPlainText = fromPlainText;
/**
* Checks whether the given value conforms to the [MarkedString](#MarkedString) type.
*/
function is(value) {
var candidate = value;
return Is.string(candidate) || (Is.objectLiteral(candidate) && Is.string(candidate.language) && Is.string(candidate.value));
}
MarkedString.is = is;
})(MarkedString || (MarkedString = {}));
var Hover;
(function (Hover) {
/**
* Checks whether the given value conforms to the [Hover](#Hover) interface.
*/
function is(value) {
var candidate = value;
return !!candidate && Is.objectLiteral(candidate) && (MarkupContent.is(candidate.contents) ||
MarkedString.is(candidate.contents) ||
Is.typedArray(candidate.contents, MarkedString.is)) && (value.range === void 0 || Range.is(value.range));
}
Hover.is = is;
})(Hover || (Hover = {}));
/**
* The ParameterInformation namespace provides helper functions to work with
* [ParameterInformation](#ParameterInformation) literals.
*/
var ParameterInformation;
(function (ParameterInformation) {
/**
* Creates a new parameter information literal.
*
* @param label A label string.
* @param documentation A doc string.
*/
function create(label, documentation) {
return documentation ? { label: label, documentation: documentation } : { label: label };
}
ParameterInformation.create = create;
;
})(ParameterInformation || (ParameterInformation = {}));
/**
* The SignatureInformation namespace provides helper functions to work with
* [SignatureInformation](#SignatureInformation) literals.
*/
var SignatureInformation;
(function (SignatureInformation) {
function create(label, documentation) {
var parameters = [];
for (var _i = 2; _i < arguments.length; _i++) {
parameters[_i - 2] = arguments[_i];
}
var result = { label: label };
if (Is.defined(documentation)) {
result.documentation = documentation;
}
if (Is.defined(parameters)) {
result.parameters = parameters;
}
else {
result.parameters = [];
}
return result;
}
SignatureInformation.create = create;
})(SignatureInformation || (SignatureInformation = {}));
/**
* A document highlight kind.
*/
var DocumentHighlightKind;
(function (DocumentHighlightKind) {
/**
* A textual occurrence.
*/
DocumentHighlightKind.Text = 1;
/**
* Read-access of a symbol, like reading a variable.
*/
DocumentHighlightKind.Read = 2;
/**
* Write-access of a symbol, like writing to a variable.
*/
DocumentHighlightKind.Write = 3;
})(DocumentHighlightKind || (DocumentHighlightKind = {}));
/**
* DocumentHighlight namespace to provide helper functions to work with
* [DocumentHighlight](#DocumentHighlight) literals.
*/
var DocumentHighlight;
(function (DocumentHighlight) {
/**
* Create a DocumentHighlight object.
* @param range The range the highlight applies to.
*/
function create(range, kind) {
var result = { range: range };
if (Is.number(kind)) {
result.kind = kind;
}
return result;
}
DocumentHighlight.create = create;
})(DocumentHighlight || (DocumentHighlight = {}));
/**
* A symbol kind.
*/
var SymbolKind;
(function (SymbolKind) {
SymbolKind.File = 1;
SymbolKind.Module = 2;
SymbolKind.Namespace = 3;
SymbolKind.Package = 4;
SymbolKind.Class = 5;
SymbolKind.Method = 6;
SymbolKind.Property = 7;
SymbolKind.Field = 8;
SymbolKind.Constructor = 9;
SymbolKind.Enum = 10;
SymbolKind.Interface = 11;
SymbolKind.Function = 12;
SymbolKind.Variable = 13;
SymbolKind.Constant = 14;
SymbolKind.String = 15;
SymbolKind.Number = 16;
SymbolKind.Boolean = 17;
SymbolKind.Array = 18;
SymbolKind.Object = 19;
SymbolKind.Key = 20;
SymbolKind.Null = 21;
SymbolKind.EnumMember = 22;
SymbolKind.Struct = 23;
SymbolKind.Event = 24;
SymbolKind.Operator = 25;
SymbolKind.TypeParameter = 26;
})(SymbolKind || (SymbolKind = {}));
var SymbolInformation;
(function (SymbolInformation) {
/**
* Creates a new symbol information literal.
*
* @param name The name of the symbol.
* @param kind The kind of the symbol.
* @param range The range of the location of the symbol.
* @param uri The resource of the location of symbol, defaults to the current document.
* @param containerName The name of the symbol containing the symbol.
*/
function create(name, kind, range, uri, containerName) {
var result = {
name: name,
kind: kind,
location: { uri: uri, range: range }
};
if (containerName) {
result.containerName = containerName;
}
return result;
}
SymbolInformation.create = create;
})(SymbolInformation || (SymbolInformation = {}));
/**
* Represents programming constructs like variables, classes, interfaces etc.
* that appear in a document. Document symbols can be hierarchical and they
* have two ranges: one that encloses its definition and one that points to
* its most interesting range, e.g. the range of an identifier.
*/
var DocumentSymbol = /** @class */ (function () {
function DocumentSymbol() {
}
return DocumentSymbol;
}());
(function (DocumentSymbol) {
/**
* Creates a new symbol information literal.
*
* @param name The name of the symbol.
* @param detail The detail of the symbol.
* @param kind The kind of the symbol.
* @param range The range of the symbol.
* @param selectionRange The selectionRange of the symbol.
* @param children Children of the symbol.
*/
function create(name, detail, kind, range, selectionRange, children) {
var result = {
name: name,
detail: detail,
kind: kind,
range: range,
selectionRange: selectionRange
};
if (children !== void 0) {
result.children = children;
}
return result;
}
DocumentSymbol.create = create;
/**
* Checks whether the given literal conforms to the [DocumentSymbol](#DocumentSymbol) interface.
*/
function is(value) {
var candidate = value;
return candidate &&
Is.string(candidate.name) && Is.number(candidate.kind) &&
Range.is(candidate.range) && Range.is(candidate.selectionRange) &&
(candidate.detail === void 0 || Is.string(candidate.detail)) &&
(candidate.deprecated === void 0 || Is.boolean(candidate.deprecated)) &&
(candidate.children === void 0 || Array.isArray(candidate.children));
}
DocumentSymbol.is = is;
})(DocumentSymbol || (DocumentSymbol = {}));
/**
* A set of predefined code action kinds
*/
var CodeActionKind;
(function (CodeActionKind) {
/**
* Base kind for quickfix actions: 'quickfix'
*/
CodeActionKind.QuickFix = 'quickfix';
/**
* Base kind for refactoring actions: 'refactor'
*/
CodeActionKind.Refactor = 'refactor';
/**
* Base kind for refactoring extraction actions: 'refactor.extract'
*
* Example extract actions:
*
* - Extract method
* - Extract function
* - Extract variable
* - Extract interface from class
* - ...
*/
CodeActionKind.RefactorExtract = 'refactor.extract';
/**
* Base kind for refactoring inline actions: 'refactor.inline'
*
* Example inline actions:
*
* - Inline function
* - Inline variable
* - Inline constant
* - ...
*/
CodeActionKind.RefactorInline = 'refactor.inline';
/**
* Base kind for refactoring rewrite actions: 'refactor.rewrite'
*
* Example rewrite actions:
*
* - Convert JavaScript function to class
* - Add or remove parameter
* - Encapsulate field
* - Make method static
* - Move method to base class
* - ...
*/
CodeActionKind.RefactorRewrite = 'refactor.rewrite';
/**
* Base kind for source actions: `source`
*
* Source code actions apply to the entire file.
*/
CodeActionKind.Source = 'source';
/**
* Base kind for an organize imports source action: `source.organizeImports`
*/
CodeActionKind.SourceOrganizeImports = 'source.organizeImports';
})(CodeActionKind || (CodeActionKind = {}));
/**
* The CodeActionContext namespace provides helper functions to work with
* [CodeActionContext](#CodeActionContext) literals.
*/
var CodeActionContext;
(function (CodeActionContext) {
/**
* Creates a new CodeActionContext literal.
*/
function create(diagnostics, only) {
var result = { diagnostics: diagnostics };
if (only !== void 0 && only !== null) {
result.only = only;
}
return result;
}
CodeActionContext.create = create;
/**
* Checks whether the given literal conforms to the [CodeActionContext](#CodeActionContext) interface.
*/
function is(value) {
var candidate = value;
return Is.defined(candidate) && Is.typedArray(candidate.diagnostics, Diagnostic.is) && (candidate.only === void 0 || Is.typedArray(candidate.only, Is.string));
}
CodeActionContext.is = is;
})(CodeActionContext || (CodeActionContext = {}));
var CodeAction;
(function (CodeAction) {
function create(title, commandOrEdit, kind) {
var result = { title: title };
if (Command.is(commandOrEdit)) {
result.command = commandOrEdit;
}
else {
result.edit = commandOrEdit;
}
if (kind !== void null) {
result.kind = kind;
}
return result;
}
CodeAction.create = create;
function is(value) {
var candidate = value;
return candidate && Is.string(candidate.title) &&
(candidate.diagnostics === void 0 || Is.typedArray(candidate.diagnostics, Diagnostic.is)) &&
(candidate.kind === void 0 || Is.string(candidate.kind)) &&
(candidate.edit !== void 0 || candidate.command !== void 0) &&
(candidate.command === void 0 || Command.is(candidate.command)) &&
(candidate.edit === void 0 || WorkspaceEdit.is(candidate.edit));
}
CodeAction.is = is;
})(CodeAction || (CodeAction = {}));
/**
* The CodeLens namespace provides helper functions to work with
* [CodeLens](#CodeLens) literals.
*/
var CodeLens;
(function (CodeLens) {
/**
* Creates a new CodeLens literal.
*/
function create(range, data) {
var result = { range: range };
if (Is.defined(data))
result.data = data;
return result;
}
CodeLens.create = create;
/**
* Checks whether the given literal conforms to the [CodeLens](#CodeLens) interface.
*/
function is(value) {
var candidate = value;
return Is.defined(candidate) && Range.is(candidate.range) && (Is.undefined(candidate.command) || Command.is(candidate.command));
}
CodeLens.is = is;
})(CodeLens || (CodeLens = {}));
/**
* The FormattingOptions namespace provides helper functions to work with
* [FormattingOptions](#FormattingOptions) literals.
*/
var FormattingOptions;
(function (FormattingOptions) {
/**
* Creates a new FormattingOptions literal.
*/
function create(tabSize, insertSpaces) {
return { tabSize: tabSize, insertSpaces: insertSpaces };
}
FormattingOptions.create = create;
/**
* Checks whether the given literal conforms to the [FormattingOptions](#FormattingOptions) interface.
*/
function is(value) {
var candidate = value;
return Is.defined(candidate) && Is.number(candidate.tabSize) && Is.boolean(candidate.insertSpaces);
}
FormattingOptions.is = is;
})(FormattingOptions || (FormattingOptions = {}));
/**
* A document link is a range in a text document that links to an internal or external resource, like another
* text document or a web site.
*/
var DocumentLink = /** @class */ (function () {
function DocumentLink() {
}
return DocumentLink;
}());
/**
* The DocumentLink namespace provides helper functions to work with
* [DocumentLink](#DocumentLink) literals.
*/
(function (DocumentLink) {
/**
* Creates a new DocumentLink literal.
*/
function create(range, target, data) {
return { range: range, target: target, data: data };
}
DocumentLink.create = create;
/**
* Checks whether the given literal conforms to the [DocumentLink](#DocumentLink) interface.
*/
function is(value) {
var candidate = value;
return Is.defined(candidate) && Range.is(candidate.range) && (Is.undefined(candidate.target) || Is.string(candidate.target));
}
DocumentLink.is = is;
})(DocumentLink || (DocumentLink = {}));
var EOL = ['\n', '\r\n', '\r'];
var TextDocument;
(function (TextDocument) {
/**
* Creates a new ITextDocument literal from the given uri and content.
* @param uri The document's uri.
* @param languageId The document's language Id.
* @param content The document's content.
*/
function create(uri, languageId, version, content) {
return new FullTextDocument(uri, languageId, version, content);
}
TextDocument.create = create;
/**
* Checks whether the given literal conforms to the [ITextDocument](#ITextDocument) interface.
*/
function is(value) {
var candidate = value;
return Is.defined(candidate) && Is.string(candidate.uri) && (Is.undefined(candidate.languageId) || Is.string(candidate.languageId)) && Is.number(candidate.lineCount)
&& Is.func(candidate.getText) && Is.func(candidate.positionAt) && Is.func(candidate.offsetAt) ? true : false;
}
TextDocument.is = is;
function applyEdits(document, edits) {
var text = document.getText();
var sortedEdits = mergeSort(edits, function (a, b) {
var diff = a.range.start.line - b.range.start.line;
if (diff === 0) {
return a.range.start.character - b.range.start.character;
}
return diff;
});
var lastModifiedOffset = text.length;
for (var i = sortedEdits.length - 1; i >= 0; i--) {
var e = sortedEdits[i];
var startOffset = document.offsetAt(e.range.start);
var endOffset = document.offsetAt(e.range.end);
if (endOffset <= lastModifiedOffset) {
text = text.substring(0, startOffset) + e.newText + text.substring(endOffset, text.length);
}
else {
throw new Error('Overlapping edit');
}
lastModifiedOffset = startOffset;
}
return text;
}
TextDocument.applyEdits = applyEdits;
function mergeSort(data, compare) {
if (data.length <= 1) {
// sorted
return data;
}
var p = (data.length / 2) | 0;
var left = data.slice(0, p);
var right = data.slice(p);
mergeSort(left, compare);
mergeSort(right, compare);
var leftIdx = 0;
var rightIdx = 0;
var i = 0;
while (leftIdx < left.length && rightIdx < right.length) {
var ret = compare(left[leftIdx], right[rightIdx]);
if (ret <= 0) {
// smaller_equal -> take left to preserve order
data[i++] = left[leftIdx++];
}
else {
// greater -> take right
data[i++] = right[rightIdx++];
}
}
while (leftIdx < left.length) {
data[i++] = left[leftIdx++];
}
while (rightIdx < right.length) {
data[i++] = right[rightIdx++];
}
return data;
}
})(TextDocument || (TextDocument = {}));
/**
* Represents reasons why a text document is saved.
*/
var TextDocumentSaveReason;
(function (TextDocumentSaveReason) {
/**
* Manually triggered, e.g. by the user pressing save, by starting debugging,
* or by an API call.
*/
TextDocumentSaveReason.Manual = 1;
/**
* Automatic after a delay.
*/
TextDocumentSaveReason.AfterDelay = 2;
/**
* When the editor lost focus.
*/
TextDocumentSaveReason.FocusOut = 3;
})(TextDocumentSaveReason || (TextDocumentSaveReason = {}));
var FullTextDocument = /** @class */ (function () {
function FullTextDocument(uri, languageId, version, content) {
this._uri = uri;
this._languageId = languageId;
this._version = version;
this._content = content;
this._lineOffsets = null;
}
Object.defineProperty(FullTextDocument.prototype, "uri", {
get: function () {
return this._uri;
},
enumerable: true,
configurable: true
});
Object.defineProperty(FullTextDocument.prototype, "languageId", {
get: function () {
return this._languageId;
},
enumerable: true,
configurable: true
});
Object.defineProperty(FullTextDocument.prototype, "version", {
get: function () {
return this._version;
},
enumerable: true,
configurable: true
});
FullTextDocument.prototype.getText = function (range) {
if (range) {
var start = this.offsetAt(range.start);
var end = this.offsetAt(range.end);
return this._content.substring(start, end);
}
return this._content;
};
FullTextDocument.prototype.update = function (event, version) {
this._content = event.text;
this._version = version;
this._lineOffsets = null;
};
FullTextDocument.prototype.getLineOffsets = function () {
if (this._lineOffsets === null) {
var lineOffsets = [];
var text = this._content;
var isLineStart = true;
for (var i = 0; i < text.length; i++) {
if (isLineStart) {
lineOffsets.push(i);
isLineStart = false;
}
var ch = text.charAt(i);
isLineStart = (ch === '\r' || ch === '\n');
if (ch === '\r' && i + 1 < text.length && text.charAt(i + 1) === '\n') {
i++;
}
}
if (isLineStart && text.length > 0) {
lineOffsets.push(text.length);
}
this._lineOffsets = lineOffsets;
}
return this._lineOffsets;
};
FullTextDocument.prototype.positionAt = function (offset) {
offset = Math.max(Math.min(offset, this._content.length), 0);
var lineOffsets = this.getLineOffsets();
var low = 0, high = lineOffsets.length;
if (high === 0) {
return Position.create(0, offset);
}
while (low < high) {
var mid = Math.floor((low + high) / 2);
if (lineOffsets[mid] > offset) {
high = mid;
}
else {
low = mid + 1;
}
}
// low is the least x for which the line offset is larger than the current offset
// or array.length if no line offset is larger than the current offset
var line = low - 1;
return Position.create(line, offset - lineOffsets[line]);
};
FullTextDocument.prototype.offsetAt = function (position) {
var lineOffsets = this.getLineOffsets();
if (position.line >= lineOffsets.length) {
return this._content.length;
}
else if (position.line < 0) {
return 0;
}
var lineOffset = lineOffsets[position.line];
var nextLineOffset = (position.line + 1 < lineOffsets.length) ? lineOffsets[position.line + 1] : this._content.length;
return Math.max(Math.min(lineOffset + position.character, nextLineOffset), lineOffset);
};
Object.defineProperty(FullTextDocument.prototype, "lineCount", {
get: function () {
return this.getLineOffsets().length;
},
enumerable: true,
configurable: true
});
return FullTextDocument;
}());
var Is;
(function (Is) {
var toString = Object.prototype.toString;
function defined(value) {
return typeof value !== 'undefined';
}
Is.defined = defined;
function undefined(value) {
return typeof value === 'undefined';
}
Is.undefined = undefined;
function boolean(value) {
return value === true || value === false;
}
Is.boolean = boolean;
function string(value) {
return toString.call(value) === '[object String]';
}
Is.string = string;
function number(value) {
return toString.call(value) === '[object Number]';
}
Is.number = number;
function func(value) {
return toString.call(value) === '[object Function]';
}
Is.func = func;
function objectLiteral(value) {
// Strictly speaking class instances pass this check as well. Since the LSP
// doesn't use classes we ignore this for now. If we do we need to add something
// like this: `Object.getPrototypeOf(Object.getPrototypeOf(x)) === null`
return value !== null && typeof value === 'object';
}
Is.objectLiteral = objectLiteral;
function typedArray(value, check) {
return Array.isArray(value) && value.every(check);
}
Is.typedArray = typedArray;
})(Is || (Is = {}));
/***/ }),
/* 19 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
Object.defineProperty(exports, "__esModule", { value: true });
const Is = __webpack_require__(20);
const vscode_jsonrpc_1 = __webpack_require__(4);
const protocol_implementation_1 = __webpack_require__(21);
exports.ImplementationRequest = protocol_implementation_1.ImplementationRequest;
const protocol_typeDefinition_1 = __webpack_require__(22);
exports.TypeDefinitionRequest = protocol_typeDefinition_1.TypeDefinitionRequest;
const protocol_workspaceFolders_1 = __webpack_require__(23);
exports.WorkspaceFoldersRequest = protocol_workspaceFolders_1.WorkspaceFoldersRequest;
exports.DidChangeWorkspaceFoldersNotification = protocol_workspaceFolders_1.DidChangeWorkspaceFoldersNotification;
const protocol_configuration_1 = __webpack_require__(24);
exports.ConfigurationRequest = protocol_configuration_1.ConfigurationRequest;
const protocol_colorProvider_1 = __webpack_require__(25);
exports.DocumentColorRequest = protocol_colorProvider_1.DocumentColorRequest;
exports.ColorPresentationRequest = protocol_colorProvider_1.ColorPresentationRequest;
const protocol_foldingRange_1 = __webpack_require__(26);
exports.FoldingRangeRequest = protocol_foldingRange_1.FoldingRangeRequest;
const protocol_declaration_1 = __webpack_require__(27);
exports.DeclarationRequest = protocol_declaration_1.DeclarationRequest;
// @ts-ignore: to avoid inlining LocatioLink as dynamic import
let __noDynamicImport;
var DocumentFilter;
(function (DocumentFilter) {
function is(value) {
let candidate = value;
return Is.string(candidate.language) || Is.string(candidate.scheme) || Is.string(candidate.pattern);
}
DocumentFilter.is = is;
})(DocumentFilter = exports.DocumentFilter || (exports.DocumentFilter = {}));
/**
* The `client/registerCapability` request is sent from the server to the client to register a new capability
* handler on the client side.
*/
var RegistrationRequest;
(function (RegistrationRequest) {
RegistrationRequest.type = new vscode_jsonrpc_1.RequestType('client/registerCapability');
})(RegistrationRequest = exports.RegistrationRequest || (exports.RegistrationRequest = {}));
/**
* The `client/unregisterCapability` request is sent from the server to the client to unregister a previously registered capability
* handler on the client side.
*/
var UnregistrationRequest;
(function (UnregistrationRequest) {
UnregistrationRequest.type = new vscode_jsonrpc_1.RequestType('client/unregisterCapability');
})(UnregistrationRequest = exports.UnregistrationRequest || (exports.UnregistrationRequest = {}));
var ResourceOperationKind;
(function (ResourceOperationKind) {
/**
* Supports creating new files and folders.
*/
ResourceOperationKind.Create = 'create';
/**
* Supports renaming existing files and folders.
*/
ResourceOperationKind.Rename = 'rename';
/**
* Supports deleting existing files and folders.
*/
ResourceOperationKind.Delete = 'delete';
})(ResourceOperationKind = exports.ResourceOperationKind || (exports.ResourceOperationKind = {}));
var FailureHandlingKind;
(function (FailureHandlingKind) {
/**
* Applying the workspace change is simply aborted if one of the changes provided
* fails. All operations executed before the failing operation stay executed.
*/
FailureHandlingKind.Abort = 'abort';
/**
* All operations are executed transactional. That means they either all
* succeed or no changes at all are applied to the workspace.
*/
FailureHandlingKind.Transactional = 'transactional';
/**
* If the workspace edit contains only textual file changes they are executed transactional.
* If resource changes (create, rename or delete file) are part of the change the failure
* handling startegy is abort.
*/
FailureHandlingKind.TextOnlyTransactional = 'textOnlyTransactional';
/**
* The client tries to undo the operations already executed. But there is no
* guaruntee that this is succeeding.
*/
FailureHandlingKind.Undo = 'undo';
})(FailureHandlingKind = exports.FailureHandlingKind || (exports.FailureHandlingKind = {}));
/**
* Defines how the host (editor) should sync
* document changes to the language server.
*/
var TextDocumentSyncKind;
(function (TextDocumentSyncKind) {
/**
* Documents should not be synced at all.
*/
TextDocumentSyncKind.None = 0;
/**
* Documents are synced by always sending the full content
* of the document.
*/
TextDocumentSyncKind.Full = 1;
/**
* Documents are synced by sending the full content on open.
* After that only incremental updates to the document are
* send.
*/
TextDocumentSyncKind.Incremental = 2;
})(TextDocumentSyncKind = exports.TextDocumentSyncKind || (exports.TextDocumentSyncKind = {}));
/**
* The initialize request is sent from the client to the server.
* It is sent once as the request after starting up the server.
* The requests parameter is of type [InitializeParams](#InitializeParams)
* the response if of type [InitializeResult](#InitializeResult) of a Thenable that
* resolves to such.
*/
var InitializeRequest;
(function (InitializeRequest) {
InitializeRequest.type = new vscode_jsonrpc_1.RequestType('initialize');
})(InitializeRequest = exports.InitializeRequest || (exports.InitializeRequest = {}));
/**
* Known error codes for an `InitializeError`;
*/
var InitializeError;
(function (InitializeError) {
/**
* If the protocol version provided by the client can't be handled by the server.
* @deprecated This initialize error got replaced by client capabilities. There is
* no version handshake in version 3.0x
*/
InitializeError.unknownProtocolVersion = 1;
})(InitializeError = exports.InitializeError || (exports.InitializeError = {}));
/**
* The intialized notification is sent from the client to the
* server after the client is fully initialized and the server
* is allowed to send requests from the server to the client.
*/
var InitializedNotification;
(function (InitializedNotification) {
InitializedNotification.type = new vscode_jsonrpc_1.NotificationType('initialized');
})(InitializedNotification = exports.InitializedNotification || (exports.InitializedNotification = {}));
//---- Shutdown Method ----
/**
* A shutdown request is sent from the client to the server.
* It is sent once when the client decides to shutdown the
* server. The only notification that is sent after a shutdown request
* is the exit event.
*/
var ShutdownRequest;
(function (ShutdownRequest) {
ShutdownRequest.type = new vscode_jsonrpc_1.RequestType0('shutdown');
})(ShutdownRequest = exports.ShutdownRequest || (exports.ShutdownRequest = {}));
//---- Exit Notification ----
/**
* The exit event is sent from the client to the server to
* ask the server to exit its process.
*/
var ExitNotification;
(function (ExitNotification) {
ExitNotification.type = new vscode_jsonrpc_1.NotificationType0('exit');
})(ExitNotification = exports.ExitNotification || (exports.ExitNotification = {}));
//---- Configuration notification ----
/**
* The configuration change notification is sent from the client to the server
* when the client's configuration has changed. The notification contains
* the changed configuration as defined by the language client.
*/
var DidChangeConfigurationNotification;
(function (DidChangeConfigurationNotification) {
DidChangeConfigurationNotification.type = new vscode_jsonrpc_1.NotificationType('workspace/didChangeConfiguration');
})(DidChangeConfigurationNotification = exports.DidChangeConfigurationNotification || (exports.DidChangeConfigurationNotification = {}));
//---- Message show and log notifications ----
/**
* The message type
*/
var MessageType;
(function (MessageType) {
/**
* An error message.
*/
MessageType.Error = 1;
/**
* A warning message.
*/
MessageType.Warning = 2;
/**
* An information message.
*/
MessageType.Info = 3;
/**
* A log message.
*/
MessageType.Log = 4;
})(MessageType = exports.MessageType || (exports.MessageType = {}));
/**
* The show message notification is sent from a server to a client to ask
* the client to display a particular message in the user interface.
*/
var ShowMessageNotification;
(function (ShowMessageNotification) {
ShowMessageNotification.type = new vscode_jsonrpc_1.NotificationType('window/showMessage');
})(ShowMessageNotification = exports.ShowMessageNotification || (exports.ShowMessageNotification = {}));
/**
* The show message request is sent from the server to the client to show a message
* and a set of options actions to the user.
*/
var ShowMessageRequest;
(function (ShowMessageRequest) {
ShowMessageRequest.type = new vscode_jsonrpc_1.RequestType('window/showMessageRequest');
})(ShowMessageRequest = exports.ShowMessageRequest || (exports.ShowMessageRequest = {}));
/**
* The log message notification is sent from the server to the client to ask
* the client to log a particular message.
*/
var LogMessageNotification;
(function (LogMessageNotification) {
LogMessageNotification.type = new vscode_jsonrpc_1.NotificationType('window/logMessage');
})(LogMessageNotification = exports.LogMessageNotification || (exports.LogMessageNotification = {}));
//---- Telemetry notification
/**
* The telemetry event notification is sent from the server to the client to ask
* the client to log telemetry data.
*/
var TelemetryEventNotification;
(function (TelemetryEventNotification) {
TelemetryEventNotification.type = new vscode_jsonrpc_1.NotificationType('telemetry/event');
})(TelemetryEventNotification = exports.TelemetryEventNotification || (exports.TelemetryEventNotification = {}));
/**
* The document open notification is sent from the client to the server to signal
* newly opened text documents. The document's truth is now managed by the client
* and the server must not try to read the document's truth using the document's
* uri. Open in this sense means it is managed by the client. It doesn't necessarily
* mean that its content is presented in an editor. An open notification must not
* be sent more than once without a corresponding close notification send before.
* This means open and close notification must be balanced and the max open count
* is one.
*/
var DidOpenTextDocumentNotification;
(function (DidOpenTextDocumentNotification) {
DidOpenTextDocumentNotification.type = new vscode_jsonrpc_1.NotificationType('textDocument/didOpen');
})(DidOpenTextDocumentNotification = exports.DidOpenTextDocumentNotification || (exports.DidOpenTextDocumentNotification = {}));
/**
* The document change notification is sent from the client to the server to signal
* changes to a text document.
*/
var DidChangeTextDocumentNotification;
(function (DidChangeTextDocumentNotification) {
DidChangeTextDocumentNotification.type = new vscode_jsonrpc_1.NotificationType('textDocument/didChange');
})(DidChangeTextDocumentNotification = exports.DidChangeTextDocumentNotification || (exports.DidChangeTextDocumentNotification = {}));
/**
* The document close notification is sent from the client to the server when
* the document got closed in the client. The document's truth now exists where
* the document's uri points to (e.g. if the document's uri is a file uri the
* truth now exists on disk). As with the open notification the close notification
* is about managing the document's content. Receiving a close notification
* doesn't mean that the document was open in an editor before. A close
* notification requires a previous open notification to be sent.
*/
var DidCloseTextDocumentNotification;
(function (DidCloseTextDocumentNotification) {
DidCloseTextDocumentNotification.type = new vscode_jsonrpc_1.NotificationType('textDocument/didClose');
})(DidCloseTextDocumentNotification = exports.DidCloseTextDocumentNotification || (exports.DidCloseTextDocumentNotification = {}));
/**
* The document save notification is sent from the client to the server when
* the document got saved in the client.
*/
var DidSaveTextDocumentNotification;
(function (DidSaveTextDocumentNotification) {
DidSaveTextDocumentNotification.type = new vscode_jsonrpc_1.NotificationType('textDocument/didSave');
})(DidSaveTextDocumentNotification = exports.DidSaveTextDocumentNotification || (exports.DidSaveTextDocumentNotification = {}));
/**
* A document will save notification is sent from the client to the server before
* the document is actually saved.
*/
var WillSaveTextDocumentNotification;
(function (WillSaveTextDocumentNotification) {
WillSaveTextDocumentNotification.type = new vscode_jsonrpc_1.NotificationType('textDocument/willSave');
})(WillSaveTextDocumentNotification = exports.WillSaveTextDocumentNotification || (exports.WillSaveTextDocumentNotification = {}));
/**
* A document will save request is sent from the client to the server before
* the document is actually saved. The request can return an array of TextEdits
* which will be applied to the text document before it is saved. Please note that
* clients might drop results if computing the text edits took too long or if a
* server constantly fails on this request. This is done to keep the save fast and
* reliable.
*/
var WillSaveTextDocumentWaitUntilRequest;
(function (WillSaveTextDocumentWaitUntilRequest) {
WillSaveTextDocumentWaitUntilRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/willSaveWaitUntil');
})(WillSaveTextDocumentWaitUntilRequest = exports.WillSaveTextDocumentWaitUntilRequest || (exports.WillSaveTextDocumentWaitUntilRequest = {}));
//---- File eventing ----
/**
* The watched files notification is sent from the client to the server when
* the client detects changes to file watched by the language client.
*/
var DidChangeWatchedFilesNotification;
(function (DidChangeWatchedFilesNotification) {
DidChangeWatchedFilesNotification.type = new vscode_jsonrpc_1.NotificationType('workspace/didChangeWatchedFiles');
})(DidChangeWatchedFilesNotification = exports.DidChangeWatchedFilesNotification || (exports.DidChangeWatchedFilesNotification = {}));
/**
* The file event type
*/
var FileChangeType;
(function (FileChangeType) {
/**
* The file got created.
*/
FileChangeType.Created = 1;
/**
* The file got changed.
*/
FileChangeType.Changed = 2;
/**
* The file got deleted.
*/
FileChangeType.Deleted = 3;
})(FileChangeType = exports.FileChangeType || (exports.FileChangeType = {}));
var WatchKind;
(function (WatchKind) {
/**
* Interested in create events.
*/
WatchKind.Create = 1;
/**
* Interested in change events
*/
WatchKind.Change = 2;
/**
* Interested in delete events
*/
WatchKind.Delete = 4;
})(WatchKind = exports.WatchKind || (exports.WatchKind = {}));
//---- Diagnostic notification ----
/**
* Diagnostics notification are sent from the server to the client to signal
* results of validation runs.
*/
var PublishDiagnosticsNotification;
(function (PublishDiagnosticsNotification) {
PublishDiagnosticsNotification.type = new vscode_jsonrpc_1.NotificationType('textDocument/publishDiagnostics');
})(PublishDiagnosticsNotification = exports.PublishDiagnosticsNotification || (exports.PublishDiagnosticsNotification = {}));
/**
* How a completion was triggered
*/
var CompletionTriggerKind;
(function (CompletionTriggerKind) {
/**
* Completion was triggered by typing an identifier (24x7 code
* complete), manual invocation (e.g Ctrl+Space) or via API.
*/
CompletionTriggerKind.Invoked = 1;
/**
* Completion was triggered by a trigger character specified by
* the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
*/
CompletionTriggerKind.TriggerCharacter = 2;
/**
* Completion was re-triggered as current completion list is incomplete
*/
CompletionTriggerKind.TriggerForIncompleteCompletions = 3;
})(CompletionTriggerKind = exports.CompletionTriggerKind || (exports.CompletionTriggerKind = {}));
/**
* Request to request completion at a given text document position. The request's
* parameter is of type [TextDocumentPosition](#TextDocumentPosition) the response
* is of type [CompletionItem[]](#CompletionItem) or [CompletionList](#CompletionList)
* or a Thenable that resolves to such.
*
* The request can delay the computation of the [`detail`](#CompletionItem.detail)
* and [`documentation`](#CompletionItem.documentation) properties to the `completionItem/resolve`
* request. However, properties that are needed for the initial sorting and filtering, like `sortText`,
* `filterText`, `insertText`, and `textEdit`, must not be changed during resolve.
*/
var CompletionRequest;
(function (CompletionRequest) {
CompletionRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/completion');
})(CompletionRequest = exports.CompletionRequest || (exports.CompletionRequest = {}));
/**
* Request to resolve additional information for a given completion item.The request's
* parameter is of type [CompletionItem](#CompletionItem) the response
* is of type [CompletionItem](#CompletionItem) or a Thenable that resolves to such.
*/
var CompletionResolveRequest;
(function (CompletionResolveRequest) {
CompletionResolveRequest.type = new vscode_jsonrpc_1.RequestType('completionItem/resolve');
})(CompletionResolveRequest = exports.CompletionResolveRequest || (exports.CompletionResolveRequest = {}));
//---- Hover Support -------------------------------
/**
* Request to request hover information at a given text document position. The request's
* parameter is of type [TextDocumentPosition](#TextDocumentPosition) the response is of
* type [Hover](#Hover) or a Thenable that resolves to such.
*/
var HoverRequest;
(function (HoverRequest) {
HoverRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/hover');
})(HoverRequest = exports.HoverRequest || (exports.HoverRequest = {}));
var SignatureHelpRequest;
(function (SignatureHelpRequest) {
SignatureHelpRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/signatureHelp');
})(SignatureHelpRequest = exports.SignatureHelpRequest || (exports.SignatureHelpRequest = {}));
//---- Goto Definition -------------------------------------
/**
* A request to resolve the definition location of a symbol at a given text
* document position. The request's parameter is of type [TextDocumentPosition]
* (#TextDocumentPosition) the response is of either type [Definition](#Definition)
* or a typed array of [DefinitionLink](#DefinitionLink) or a Thenable that resolves
* to such.
*/
var DefinitionRequest;
(function (DefinitionRequest) {
DefinitionRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/definition');
})(DefinitionRequest = exports.DefinitionRequest || (exports.DefinitionRequest = {}));
/**
* A request to resolve project-wide references for the symbol denoted
* by the given text document position. The request's parameter is of
* type [ReferenceParams](#ReferenceParams) the response is of type
* [Location[]](#Location) or a Thenable that resolves to such.
*/
var ReferencesRequest;
(function (ReferencesRequest) {
ReferencesRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/references');
})(ReferencesRequest = exports.ReferencesRequest || (exports.ReferencesRequest = {}));
//---- Document Highlight ----------------------------------
/**
* Request to resolve a [DocumentHighlight](#DocumentHighlight) for a given
* text document position. The request's parameter is of type [TextDocumentPosition]
* (#TextDocumentPosition) the request response is of type [DocumentHighlight[]]
* (#DocumentHighlight) or a Thenable that resolves to such.
*/
var DocumentHighlightRequest;
(function (DocumentHighlightRequest) {
DocumentHighlightRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/documentHighlight');
})(DocumentHighlightRequest = exports.DocumentHighlightRequest || (exports.DocumentHighlightRequest = {}));
//---- Document Symbol Provider ---------------------------
/**
* A request to list all symbols found in a given text document. The request's
* parameter is of type [TextDocumentIdentifier](#TextDocumentIdentifier) the
* response is of type [SymbolInformation[]](#SymbolInformation) or a Thenable
* that resolves to such.
*/
var DocumentSymbolRequest;
(function (DocumentSymbolRequest) {
DocumentSymbolRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/documentSymbol');
})(DocumentSymbolRequest = exports.DocumentSymbolRequest || (exports.DocumentSymbolRequest = {}));
//---- Workspace Symbol Provider ---------------------------
/**
* A request to list project-wide symbols matching the query string given
* by the [WorkspaceSymbolParams](#WorkspaceSymbolParams). The response is
* of type [SymbolInformation[]](#SymbolInformation) or a Thenable that
* resolves to such.
*/
var WorkspaceSymbolRequest;
(function (WorkspaceSymbolRequest) {
WorkspaceSymbolRequest.type = new vscode_jsonrpc_1.RequestType('workspace/symbol');
})(WorkspaceSymbolRequest = exports.WorkspaceSymbolRequest || (exports.WorkspaceSymbolRequest = {}));
/**
* A request to provide commands for the given text document and range.
*/
var CodeActionRequest;
(function (CodeActionRequest) {
CodeActionRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/codeAction');
})(CodeActionRequest = exports.CodeActionRequest || (exports.CodeActionRequest = {}));
/**
* A request to provide code lens for the given text document.
*/
var CodeLensRequest;
(function (CodeLensRequest) {
CodeLensRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/codeLens');
})(CodeLensRequest = exports.CodeLensRequest || (exports.CodeLensRequest = {}));
/**
* A request to resolve a command for a given code lens.
*/
var CodeLensResolveRequest;
(function (CodeLensResolveRequest) {
CodeLensResolveRequest.type = new vscode_jsonrpc_1.RequestType('codeLens/resolve');
})(CodeLensResolveRequest = exports.CodeLensResolveRequest || (exports.CodeLensResolveRequest = {}));
/**
* A request to to format a whole document.
*/
var DocumentFormattingRequest;
(function (DocumentFormattingRequest) {
DocumentFormattingRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/formatting');
})(DocumentFormattingRequest = exports.DocumentFormattingRequest || (exports.DocumentFormattingRequest = {}));
/**
* A request to to format a range in a document.
*/
var DocumentRangeFormattingRequest;
(function (DocumentRangeFormattingRequest) {
DocumentRangeFormattingRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/rangeFormatting');
})(DocumentRangeFormattingRequest = exports.DocumentRangeFormattingRequest || (exports.DocumentRangeFormattingRequest = {}));
/**
* A request to format a document on type.
*/
var DocumentOnTypeFormattingRequest;
(function (DocumentOnTypeFormattingRequest) {
DocumentOnTypeFormattingRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/onTypeFormatting');
})(DocumentOnTypeFormattingRequest = exports.DocumentOnTypeFormattingRequest || (exports.DocumentOnTypeFormattingRequest = {}));
/**
* A request to rename a symbol.
*/
var RenameRequest;
(function (RenameRequest) {
RenameRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/rename');
})(RenameRequest = exports.RenameRequest || (exports.RenameRequest = {}));
/**
* A request to test and perform the setup necessary for a rename.
*/
var PrepareRenameRequest;
(function (PrepareRenameRequest) {
PrepareRenameRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/prepareRename');
})(PrepareRenameRequest = exports.PrepareRenameRequest || (exports.PrepareRenameRequest = {}));
/**
* A request to provide document links
*/
var DocumentLinkRequest;
(function (DocumentLinkRequest) {
DocumentLinkRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/documentLink');
})(DocumentLinkRequest = exports.DocumentLinkRequest || (exports.DocumentLinkRequest = {}));
/**
* Request to resolve additional information for a given document link. The request's
* parameter is of type [DocumentLink](#DocumentLink) the response
* is of type [DocumentLink](#DocumentLink) or a Thenable that resolves to such.
*/
var DocumentLinkResolveRequest;
(function (DocumentLinkResolveRequest) {
DocumentLinkResolveRequest.type = new vscode_jsonrpc_1.RequestType('documentLink/resolve');
})(DocumentLinkResolveRequest = exports.DocumentLinkResolveRequest || (exports.DocumentLinkResolveRequest = {}));
/**
* A request send from the client to the server to execute a command. The request might return
* a workspace edit which the client will apply to the workspace.
*/
var ExecuteCommandRequest;
(function (ExecuteCommandRequest) {
ExecuteCommandRequest.type = new vscode_jsonrpc_1.RequestType('workspace/executeCommand');
})(ExecuteCommandRequest = exports.ExecuteCommandRequest || (exports.ExecuteCommandRequest = {}));
/**
* A request sent from the server to the client to modified certain resources.
*/
var ApplyWorkspaceEditRequest;
(function (ApplyWorkspaceEditRequest) {
ApplyWorkspaceEditRequest.type = new vscode_jsonrpc_1.RequestType('workspace/applyEdit');
})(ApplyWorkspaceEditRequest = exports.ApplyWorkspaceEditRequest || (exports.ApplyWorkspaceEditRequest = {}));
/***/ }),
/* 20 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
Object.defineProperty(exports, "__esModule", { value: true });
function boolean(value) {
return value === true || value === false;
}
exports.boolean = boolean;
function string(value) {
return typeof value === 'string' || value instanceof String;
}
exports.string = string;
function number(value) {
return typeof value === 'number' || value instanceof Number;
}
exports.number = number;
function error(value) {
return value instanceof Error;
}
exports.error = error;
function func(value) {
return typeof value === 'function';
}
exports.func = func;
function array(value) {
return Array.isArray(value);
}
exports.array = array;
function stringArray(value) {
return array(value) && value.every(elem => string(elem));
}
exports.stringArray = stringArray;
function typedArray(value, check) {
return Array.isArray(value) && value.every(check);
}
exports.typedArray = typedArray;
function thenable(value) {
return value && func(value.then);
}
exports.thenable = thenable;
/***/ }),
/* 21 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_jsonrpc_1 = __webpack_require__(4);
// @ts-ignore: to avoid inlining LocatioLink as dynamic import
let __noDynamicImport;
/**
* A request to resolve the implementation locations of a symbol at a given text
* document position. The request's parameter is of type [TextDocumentPositioParams]
* (#TextDocumentPositionParams) the response is of type [Definition](#Definition) or a
* Thenable that resolves to such.
*/
var ImplementationRequest;
(function (ImplementationRequest) {
ImplementationRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/implementation');
})(ImplementationRequest = exports.ImplementationRequest || (exports.ImplementationRequest = {}));
/***/ }),
/* 22 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_jsonrpc_1 = __webpack_require__(4);
// @ts-ignore: to avoid inlining LocatioLink as dynamic import
let __noDynamicImport;
/**
* A request to resolve the type definition locations of a symbol at a given text
* document position. The request's parameter is of type [TextDocumentPositioParams]
* (#TextDocumentPositionParams) the response is of type [Definition](#Definition) or a
* Thenable that resolves to such.
*/
var TypeDefinitionRequest;
(function (TypeDefinitionRequest) {
TypeDefinitionRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/typeDefinition');
})(TypeDefinitionRequest = exports.TypeDefinitionRequest || (exports.TypeDefinitionRequest = {}));
/***/ }),
/* 23 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_jsonrpc_1 = __webpack_require__(4);
/**
* The `workspace/workspaceFolders` is sent from the server to the client to fetch the open workspace folders.
*/
var WorkspaceFoldersRequest;
(function (WorkspaceFoldersRequest) {
WorkspaceFoldersRequest.type = new vscode_jsonrpc_1.RequestType0('workspace/workspaceFolders');
})(WorkspaceFoldersRequest = exports.WorkspaceFoldersRequest || (exports.WorkspaceFoldersRequest = {}));
/**
* The `workspace/didChangeWorkspaceFolders` notification is sent from the client to the server when the workspace
* folder configuration changes.
*/
var DidChangeWorkspaceFoldersNotification;
(function (DidChangeWorkspaceFoldersNotification) {
DidChangeWorkspaceFoldersNotification.type = new vscode_jsonrpc_1.NotificationType('workspace/didChangeWorkspaceFolders');
})(DidChangeWorkspaceFoldersNotification = exports.DidChangeWorkspaceFoldersNotification || (exports.DidChangeWorkspaceFoldersNotification = {}));
/***/ }),
/* 24 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_jsonrpc_1 = __webpack_require__(4);
/**
* The 'workspace/configuration' request is sent from the server to the client to fetch a certain
* configuration setting.
*
* This pull model replaces the old push model were the client signaled configuration change via an
* event. If the server still needs to react to configuration changes (since the server caches the
* result of `workspace/configuration` requests) the server should register for an empty configuration
* change event and empty the cache if such an event is received.
*/
var ConfigurationRequest;
(function (ConfigurationRequest) {
ConfigurationRequest.type = new vscode_jsonrpc_1.RequestType('workspace/configuration');
})(ConfigurationRequest = exports.ConfigurationRequest || (exports.ConfigurationRequest = {}));
/***/ }),
/* 25 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_jsonrpc_1 = __webpack_require__(4);
/**
* A request to list all color symbols found in a given text document. The request's
* parameter is of type [DocumentColorParams](#DocumentColorParams) the
* response is of type [ColorInformation[]](#ColorInformation) or a Thenable
* that resolves to such.
*/
var DocumentColorRequest;
(function (DocumentColorRequest) {
DocumentColorRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/documentColor');
})(DocumentColorRequest = exports.DocumentColorRequest || (exports.DocumentColorRequest = {}));
/**
* A request to list all presentation for a color. The request's
* parameter is of type [ColorPresentationParams](#ColorPresentationParams) the
* response is of type [ColorInformation[]](#ColorInformation) or a Thenable
* that resolves to such.
*/
var ColorPresentationRequest;
(function (ColorPresentationRequest) {
ColorPresentationRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/colorPresentation');
})(ColorPresentationRequest = exports.ColorPresentationRequest || (exports.ColorPresentationRequest = {}));
/***/ }),
/* 26 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_jsonrpc_1 = __webpack_require__(4);
/**
* Enum of known range kinds
*/
var FoldingRangeKind;
(function (FoldingRangeKind) {
/**
* Folding range for a comment
*/
FoldingRangeKind["Comment"] = "comment";
/**
* Folding range for a imports or includes
*/
FoldingRangeKind["Imports"] = "imports";
/**
* Folding range for a region (e.g. `#region`)
*/
FoldingRangeKind["Region"] = "region";
})(FoldingRangeKind = exports.FoldingRangeKind || (exports.FoldingRangeKind = {}));
/**
* A request to provide folding ranges in a document. The request's
* parameter is of type [FoldingRangeParams](#FoldingRangeParams), the
* response is of type [FoldingRangeList](#FoldingRangeList) or a Thenable
* that resolves to such.
*/
var FoldingRangeRequest;
(function (FoldingRangeRequest) {
FoldingRangeRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/foldingRange');
})(FoldingRangeRequest = exports.FoldingRangeRequest || (exports.FoldingRangeRequest = {}));
/***/ }),
/* 27 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_jsonrpc_1 = __webpack_require__(4);
// @ts-ignore: to avoid inlining LocatioLink as dynamic import
let __noDynamicImport;
/**
* A request to resolve the type definition locations of a symbol at a given text
* document position. The request's parameter is of type [TextDocumentPositioParams]
* (#TextDocumentPositionParams) the response is of type [Declaration](#Declaration)
* or a typed array of [DeclarationLink](#DeclarationLink) or a Thenable that resolves
* to such.
*/
var DeclarationRequest;
(function (DeclarationRequest) {
DeclarationRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/declaration');
})(DeclarationRequest = exports.DeclarationRequest || (exports.DeclarationRequest = {}));
/***/ }),
/* 28 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* --------------------------------------------------------------------------------------------
* Copyright (c) TypeFox and others. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_jsonrpc_1 = __webpack_require__(4);
/**
* The direction of a call hierarchy request.
*/
var CallHierarchyDirection;
(function (CallHierarchyDirection) {
/**
* The callers
*/
CallHierarchyDirection.CallsFrom = 1;
/**
* The callees
*/
CallHierarchyDirection.CallsTo = 2;
})(CallHierarchyDirection = exports.CallHierarchyDirection || (exports.CallHierarchyDirection = {}));
/**
* Request to provide the call hierarchy at a given text document position.
*
* The request's parameter is of type [CallHierarchyParams](#CallHierarchyParams). The response
* is of type [CallHierarchyCall[]](#CallHierarchyCall) or a Thenable that resolves to such.
*
* Evaluates the symbol defined (or referenced) at the given position, and returns all incoming or outgoing calls to the symbol(s).
*/
var CallHierarchyRequest;
(function (CallHierarchyRequest) {
CallHierarchyRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/callHierarchy');
})(CallHierarchyRequest = exports.CallHierarchyRequest || (exports.CallHierarchyRequest = {}));
/***/ }),
/* 29 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_jsonrpc_1 = __webpack_require__(4);
/**
* The `window/progress/start` notification is sent from the server to the client
* to initiate a progress.
*/
var ProgressStartNotification;
(function (ProgressStartNotification) {
ProgressStartNotification.type = new vscode_jsonrpc_1.NotificationType('window/progress/start');
})(ProgressStartNotification = exports.ProgressStartNotification || (exports.ProgressStartNotification = {}));
/**
* The `window/progress/report` notification is sent from the server to the client
* to initiate a progress.
*/
var ProgressReportNotification;
(function (ProgressReportNotification) {
ProgressReportNotification.type = new vscode_jsonrpc_1.NotificationType('window/progress/report');
})(ProgressReportNotification = exports.ProgressReportNotification || (exports.ProgressReportNotification = {}));
/**
* The `window/progress/done` notification is sent from the server to the client
* to initiate a progress.
*/
var ProgressDoneNotification;
(function (ProgressDoneNotification) {
ProgressDoneNotification.type = new vscode_jsonrpc_1.NotificationType('window/progress/done');
})(ProgressDoneNotification = exports.ProgressDoneNotification || (exports.ProgressDoneNotification = {}));
/**
* The `window/progress/cancel` notification is sent client to the server to cancel a progress
* initiated on the server side.
*/
var ProgressCancelNotification;
(function (ProgressCancelNotification) {
ProgressCancelNotification.type = new vscode_jsonrpc_1.NotificationType('window/progress/cancel');
})(ProgressCancelNotification = exports.ProgressCancelNotification || (exports.ProgressCancelNotification = {}));
/***/ }),
/* 30 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_jsonrpc_1 = __webpack_require__(4);
const vscode_languageserver_types_1 = __webpack_require__(18);
/**
* The SelectionRange namespace provides helper function to work with
* SelectionRange literals.
*/
var SelectionRange;
(function (SelectionRange) {
/**
* Creates a new SelectionRange
* @param range the range.
* @param parent an optional parent.
*/
function create(range, parent) {
return { range, parent };
}
SelectionRange.create = create;
function is(value) {
let candidate = value;
return candidate !== undefined && vscode_languageserver_types_1.Range.is(candidate.range) && (candidate.parent === undefined || SelectionRange.is(candidate.parent));
}
SelectionRange.is = is;
})(SelectionRange = exports.SelectionRange || (exports.SelectionRange = {}));
/**
* A request to provide selection ranges in a document. The request's
* parameter is of type [SelectionRangeParams](#SelectionRangeParams), the
* response is of type [SelectionRange[]](#SelectionRange[]) or a Thenable
* that resolves to such.
*/
var SelectionRangeRequest;
(function (SelectionRangeRequest) {
SelectionRangeRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/selectionRange');
})(SelectionRangeRequest = exports.SelectionRangeRequest || (exports.SelectionRangeRequest = {}));
/***/ }),
/* 31 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const coc_nvim_1 = __webpack_require__(1);
const vscode_languageserver_protocol_1 = __webpack_require__(3);
const util_1 = __webpack_require__(32);
const hexColorRegex = /^#[\d,a-f,A-F]{0,6}$/;
/**
* Checks if given position is a valid location to expand emmet abbreviation.
* Works only on html and css/less/scss syntax
* @param document current Text Document
* @param rootNode parsed document
* @param currentNode current node in the parsed document
* @param syntax syntax of the abbreviation
* @param position position to validate
* @param abbreviationRange The range of the abbreviation for which given position is being validated
*/
function isValidLocationForEmmetAbbreviation(document, rootNode, currentNode, syntax, position, abbreviationRange) {
if (util_1.isStyleSheet(syntax)) {
const stylesheet = rootNode;
if (stylesheet &&
(stylesheet.comments || []).some(x => util_1.comparePosition(position, x.start) >= 0 && util_1.comparePosition(position, x.end) <= 0)) {
return false;
}
// Continue validation only if the file was parse-able and the currentNode has been found
if (!currentNode) {
return true;
}
// Fix for https://github.com/Microsoft/issues/34162
// Other than sass, stylus, we can make use of the terminator tokens to validate position
if (syntax !== 'sass' && syntax !== 'stylus' && currentNode.type === 'property') {
// Fix for upstream issue https://github.com/emmetio/css-parser/issues/3
if (currentNode.parent
&& currentNode.parent.type !== 'rule'
&& currentNode.parent.type !== 'at-rule') {
return false;
}
const abbreviation = document.getText(vscode_languageserver_protocol_1.Range.create(abbreviationRange.start.line, abbreviationRange.start.character, abbreviationRange.end.line, abbreviationRange.end.character));
const propertyNode = currentNode;
if (propertyNode.terminatorToken
&& propertyNode.separator
&& util_1.comparePosition(position, propertyNode.separatorToken.end) >= 0
&& util_1.comparePosition(position, propertyNode.terminatorToken.start) <= 0
&& abbreviation.indexOf(':') === -1) {
return hexColorRegex.test(abbreviation) || abbreviation === '!';
}
if (!propertyNode.terminatorToken
&& propertyNode.separator
&& util_1.comparePosition(position, propertyNode.separatorToken.end) >= 0
&& abbreviation.indexOf(':') === -1) {
return hexColorRegex.test(abbreviation) || abbreviation === '!';
}
if (hexColorRegex.test(abbreviation) || abbreviation === '!') {
return false;
}
}
// If current node is a rule or at-rule, then perform additional checks to ensure
// emmet suggestions are not provided in the rule selector
if (currentNode.type !== 'rule' && currentNode.type !== 'at-rule') {
return true;
}
const currentCssNode = currentNode;
// Position is valid if it occurs after the `{` that marks beginning of rule contents
if (util_1.comparePosition(position, currentCssNode.contentStartToken.end) > 0) {
return true;
}
// Workaround for https://github.com/Microsoft/30188
// The line above the rule selector is considered as part of the selector by the css-parser
// But we should assume it is a valid location for css properties under the parent rule
if (currentCssNode.parent
&& (currentCssNode.parent.type === 'rule' || currentCssNode.parent.type === 'at-rule')
&& currentCssNode.selectorToken
&& position.line !== currentCssNode.selectorToken.end.line
&& currentCssNode.selectorToken.start.character === abbreviationRange.start.character
&& currentCssNode.selectorToken.start.line === abbreviationRange.start.line) {
return true;
}
return false;
}
const startAngle = '<';
const endAngle = '>';
const escape = '\\';
const question = '?';
const currentHtmlNode = currentNode;
let start = vscode_languageserver_protocol_1.Position.create(0, 0);
if (currentHtmlNode) {
if (currentHtmlNode.name === 'script') {
const typeAttribute = (currentHtmlNode.attributes || []).filter(x => x.name.toString() === 'type')[0];
const typeValue = typeAttribute ? typeAttribute.value.toString() : '';
if (util_1.allowedMimeTypesInScriptTag.indexOf(typeValue) > -1) {
return true;
}
const isScriptJavascriptType = !typeValue || typeValue === 'application/javascript' || typeValue === 'text/javascript';
if (isScriptJavascriptType) {
return !!getSyntaxFromArgs({ language: 'javascript' });
}
return false;
}
const innerRange = util_1.getInnerRange(currentHtmlNode);
// Fix for https://github.com/Microsoft/issues/28829
if (!innerRange || !util_1.positionInRange(position, innerRange)) {
return false;
}
// Fix for https://github.com/Microsoft/issues/35128
// Find the position up till where we will backtrack looking for unescaped < or >
// to decide if current position is valid for emmet expansion
start = innerRange.start;
let lastChildBeforePosition = currentHtmlNode.firstChild;
while (lastChildBeforePosition) {
if (util_1.comparePosition(lastChildBeforePosition.end, position) > 0) {
break;
}
start = lastChildBeforePosition.end;
lastChildBeforePosition = lastChildBeforePosition.nextSibling;
}
}
let textToBackTrack = document.getText(vscode_languageserver_protocol_1.Range.create(start.line, start.character, abbreviationRange.start.line, abbreviationRange.start.character));
// Worse case scenario is when cursor is inside a big chunk of text which needs to backtracked
// Backtrack only 500 offsets to ensure we dont waste time doing this
if (textToBackTrack.length > 500) {
textToBackTrack = textToBackTrack.substr(textToBackTrack.length - 500);
}
if (!textToBackTrack.trim()) {
return true;
}
let valid = true;
let foundSpace = false; // If < is found before finding whitespace, then its valid abbreviation. Eg: <div|
let i = textToBackTrack.length - 1;
if (textToBackTrack[i] === startAngle) {
return false;
}
while (i >= 0) {
const char = textToBackTrack[i];
i--;
if (!foundSpace && /\s/.test(char)) {
foundSpace = true;
continue;
}
if (char === question && textToBackTrack[i] === startAngle) {
i--;
continue;
}
// Fix for https://github.com/Microsoft/issues/55411
// A space is not a valid character right after < in a tag name.
if (/\s/.test(char) && textToBackTrack[i] === startAngle) {
i--;
continue;
}
if (char !== startAngle && char !== endAngle) {
continue;
}
if (i >= 0 && textToBackTrack[i] === escape) {
i--;
continue;
}
if (char === endAngle) {
if (i >= 0 && textToBackTrack[i] === '=') {
continue; // False alarm of cases like =>
}
else {
break;
}
}
if (char === startAngle) {
valid = !foundSpace;
break;
}
}
return valid;
}
exports.isValidLocationForEmmetAbbreviation = isValidLocationForEmmetAbbreviation;
function getSyntaxFromArgs(args) {
const mappedModes = util_1.getMappingForIncludedLanguages();
const language = args['language'];
const parentMode = args['parentMode'];
const excludedLanguages = coc_nvim_1.workspace.getConfiguration('emmet')['excludeLanguages'] ? coc_nvim_1.workspace.getConfiguration('emmet')['excludeLanguages'] : [];
if (excludedLanguages.indexOf(language) > -1) {
return;
}
let syntax = util_1.getEmmetMode((mappedModes[language] ? mappedModes[language] : language), excludedLanguages);
if (!syntax) {
syntax = util_1.getEmmetMode((mappedModes[parentMode] ? mappedModes[parentMode] : parentMode), excludedLanguages);
}
return syntax;
}
/***/ }),
/* 32 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const coc_nvim_1 = __webpack_require__(1);
const vscode_languageserver_protocol_1 = __webpack_require__(3);
const html_matcher_1 = __importDefault(__webpack_require__(33));
const css_parser_1 = __importDefault(__webpack_require__(36));
const bufferStream_1 = __webpack_require__(37);
exports.comparePosition = bufferStream_1.comparePosition;
let _emmetHelper;
let _currentExtensionsPath;
function positionInRange(position, range) {
let { start, end } = range;
if (bufferStream_1.comparePosition(position, start) < 0)
return -1;
if (bufferStream_1.comparePosition(position, end) > 0)
return 1;
return 0;
}
exports.positionInRange = positionInRange;
function getEmmetHelper() {
// Lazy load emmet-helper instead of importing it
// directly to reduce the start-up time of the extension
if (!_emmetHelper) {
_emmetHelper = __webpack_require__(38);
}
updateEmmetExtensionsPath();
return _emmetHelper;
}
exports.getEmmetHelper = getEmmetHelper;
/**
* Update Emmet Helper to use user snippets from the extensionsPath setting
*/
function updateEmmetExtensionsPath() {
if (!_emmetHelper) {
return;
}
let extensionsPath = coc_nvim_1.workspace.getConfiguration('emmet')['extensionsPath'];
if (_currentExtensionsPath !== extensionsPath) {
_currentExtensionsPath = extensionsPath;
_emmetHelper.updateExtensionsPath(extensionsPath, coc_nvim_1.workspace.rootPath).then(null, (err) => coc_nvim_1.workspace.showMessage(err, 'error'));
}
}
exports.updateEmmetExtensionsPath = updateEmmetExtensionsPath;
/**
* Mapping between languages that support Emmet and completion trigger characters
*/
exports.LANGUAGE_MODES = {
'html': ['!', '.', '}', ':', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'jade': ['!', '.', '}', ':', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'slim': ['!', '.', '}', ':', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'haml': ['!', '.', '}', ':', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'xml': ['.', '}', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'xsl': ['!', '.', '}', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'css': [':', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'scss': [':', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'sass': [':', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'less': [':', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'stylus': [':', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'javascriptreact': ['!', '.', '}', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'typescriptreact': ['!', '.', '}', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
};
function isStyleSheet(syntax) {
let stylesheetSyntaxes = ['css', 'scss', 'sass', 'less', 'stylus', 'wxss'];
return (stylesheetSyntaxes.indexOf(syntax) > -1);
}
exports.isStyleSheet = isStyleSheet;
function validate(allowStylesheet = true) {
let doc = coc_nvim_1.workspace.getDocument(coc_nvim_1.workspace.bufnr);
if (!doc)
return false;
if (!allowStylesheet && isStyleSheet(doc.filetype)) {
return false;
}
return true;
}
exports.validate = validate;
function getMappingForIncludedLanguages() {
// Explicitly map languages that have built-in grammar in VS Code to their parent language
// to get emmet completion support
// For other languages, users will have to use `emmet.includeLanguages` or
// language specific extensions can provide emmet completion support
const MAPPED_MODES = {
'handlebars': 'html',
'php': 'html'
};
const finalMappedModes = Object.create(null);
let includeLanguagesConfig = coc_nvim_1.workspace.getConfiguration('emmet')['includeLanguages'];
let includeLanguages = Object.assign({}, MAPPED_MODES, includeLanguagesConfig ? includeLanguagesConfig : {});
Object.keys(includeLanguages).forEach(syntax => {
if (typeof includeLanguages[syntax] === 'string' && exports.LANGUAGE_MODES[includeLanguages[syntax]]) {
finalMappedModes[syntax] = includeLanguages[syntax];
}
});
return finalMappedModes;
}
exports.getMappingForIncludedLanguages = getMappingForIncludedLanguages;
/**
* Get the corresponding emmet mode for given language mode
* Eg: jsx for typescriptreact/javascriptreact or pug for jade
* If the language is not supported by emmet or has been exlcuded via `exlcudeLanguages` setting,
* then nothing is returned
*
* @param language
* @param exlcudedLanguages Array of language ids that user has chosen to exlcude for emmet
*/
function getEmmetMode(language, excludedLanguages) {
if (!language || excludedLanguages.indexOf(language) > -1) {
return;
}
if (/\b(typescriptreact|javascriptreact|jsx-tags)\b/.test(language)) { // treat tsx like jsx
return 'jsx';
}
if (language === 'sass-indented') { // map sass-indented to sass
return 'sass';
}
if (language === 'jade') {
return 'pug';
}
const emmetModes = ['html', 'pug', 'slim', 'haml', 'xml', 'xsl', 'jsx', 'css', 'scss', 'sass', 'less', 'stylus'];
if (emmetModes.indexOf(language) > -1) {
return language;
}
return;
}
exports.getEmmetMode = getEmmetMode;
/**
* Parses the given document using emmet parsing modules
*/
function parseDocument(document, showError = true) {
let parseContent = isStyleSheet(document.languageId) ? css_parser_1.default : html_matcher_1.default;
try {
return parseContent(new bufferStream_1.DocumentStreamReader(document));
}
catch (e) {
if (showError) {
console.error('Emmet: Failed to parse the file');
}
}
return undefined;
}
exports.parseDocument = parseDocument;
const closeBrace = 125;
const openBrace = 123;
const slash = 47;
const star = 42;
/**
* Traverse the given document backward & forward from given position
* to find a complete ruleset, then parse just that to return a Stylesheet
* @param document TextDocument
* @param position Position
*/
function parsePartialStylesheet(document, position) {
const isCSS = document.languageId === 'css';
let startPosition = vscode_languageserver_protocol_1.Position.create(0, 0);
let lastLine = document.getText(vscode_languageserver_protocol_1.Range.create(document.lineCount - 1, 0, document.lineCount, 0)).replace(/\n$/, '');
let endPosition = vscode_languageserver_protocol_1.Position.create(document.lineCount - 1, lastLine.length);
const limitCharacter = document.offsetAt(position) - 5000;
const limitPosition = limitCharacter > 0 ? document.positionAt(limitCharacter) : startPosition;
const stream = new bufferStream_1.DocumentStreamReader(document, position);
function findOpeningCommentBeforePosition(pos) {
let text = document.getText(vscode_languageserver_protocol_1.Range.create(0, 0, pos.line, pos.character));
let offset = text.lastIndexOf('/*');
if (offset === -1) {
return;
}
return document.positionAt(offset);
}
function findClosingCommentAfterPosition(pos) {
let text = document.getText(vscode_languageserver_protocol_1.Range.create(pos.line, pos.character, document.lineCount - 1, lastLine.length));
let offset = text.indexOf('*/');
if (offset === -1) {
return;
}
offset += 2 + document.offsetAt(pos);
return document.positionAt(offset);
}
function consumeLineCommentBackwards() {
if (!isCSS && currentLine !== stream.pos.line) {
currentLine = stream.pos.line;
let line = document.getText(vscode_languageserver_protocol_1.Range.create(currentLine, 0, currentLine + 1, 0));
let startLineComment = line.indexOf('//');
if (startLineComment > -1) {
stream.pos = vscode_languageserver_protocol_1.Position.create(currentLine, startLineComment);
}
}
}
function consumeBlockCommentBackwards() {
if (stream.peek() === slash) {
if (stream.backUp(1) === star) {
stream.pos = findOpeningCommentBeforePosition(stream.pos) || startPosition;
}
else {
stream.next();
}
}
}
function consumeCommentForwards() {
if (stream.eat(slash)) {
if (stream.eat(slash) && !isCSS) {
stream.pos = vscode_languageserver_protocol_1.Position.create(stream.pos.line + 1, 0);
}
else if (stream.eat(star)) {
stream.pos = findClosingCommentAfterPosition(stream.pos) || endPosition;
}
}
}
// Go forward until we find a closing brace.
while (!stream.eof() && !stream.eat(closeBrace)) {
if (stream.peek() === slash) {
consumeCommentForwards();
}
else {
stream.next();
}
}
if (!stream.eof()) {
endPosition = stream.pos;
}
stream.pos = position;
let openBracesToFind = 1;
let currentLine = position.line;
let exit = false;
// Go back until we found an opening brace. If we find a closing one, consume its pair and continue.
while (!exit && openBracesToFind > 0 && !stream.sof()) {
consumeLineCommentBackwards();
switch (stream.backUp(1)) {
case openBrace:
openBracesToFind--;
break;
case closeBrace:
if (isCSS) {
stream.next();
startPosition = stream.pos;
exit = true;
}
else {
openBracesToFind++;
}
break;
case slash:
consumeBlockCommentBackwards();
break;
default:
break;
}
if (position.line - stream.pos.line > 100 || bufferStream_1.comparePosition(stream.pos, limitPosition) <= 0) {
exit = true;
}
}
// We are at an opening brace. We need to include its selector.
currentLine = stream.pos.line;
openBracesToFind = 0;
let foundSelector = false;
while (!exit && !stream.sof() && !foundSelector && openBracesToFind >= 0) {
consumeLineCommentBackwards();
const ch = stream.backUp(1);
if (/\s/.test(String.fromCharCode(ch))) {
continue;
}
switch (ch) {
case slash:
consumeBlockCommentBackwards();
break;
case closeBrace:
openBracesToFind++;
break;
case openBrace:
openBracesToFind--;
break;
default:
if (!openBracesToFind) {
foundSelector = true;
}
break;
}
if (!stream.sof() && foundSelector) {
startPosition = stream.pos;
}
}
try {
return css_parser_1.default(new bufferStream_1.DocumentStreamReader(document, startPosition, vscode_languageserver_protocol_1.Range.create(startPosition, endPosition)));
}
catch (e) {
return;
}
}
exports.parsePartialStylesheet = parsePartialStylesheet;
/**
* Returns node corresponding to given position in the given root node
*/
function getNode(root, position, includeNodeBoundary) {
if (!root) {
return null;
}
let currentNode = root.firstChild;
let foundNode = null;
while (currentNode) {
const nodeStart = currentNode.start;
const nodeEnd = currentNode.end;
if ((bufferStream_1.comparePosition(nodeStart, position) < 0 && bufferStream_1.comparePosition(nodeEnd, position) > 0)
|| (includeNodeBoundary && (bufferStream_1.comparePosition(nodeStart, position) <= 0 && bufferStream_1.comparePosition(nodeEnd, position) >= 0))) {
foundNode = currentNode;
// Dig deeper
currentNode = currentNode.firstChild;
}
else {
currentNode = currentNode.nextSibling;
}
}
return foundNode;
}
exports.getNode = getNode;
exports.allowedMimeTypesInScriptTag = ['text/html', 'text/plain', 'text/x-template', 'text/template', 'text/ng-template'];
/**
* Returns inner range of an html node.
* @param currentNode
*/
function getInnerRange(currentNode) {
if (!currentNode.close) {
return undefined;
}
return vscode_languageserver_protocol_1.Range.create(currentNode.open.end, currentNode.close.start);
}
exports.getInnerRange = getInnerRange;
/**
* Returns the deepest non comment node under given node
* @param node
*/
function getDeepestNode(node) {
if (!node || !node.children || node.children.length === 0 || !node.children.find(x => x.type !== 'comment')) {
return node;
}
for (let i = node.children.length - 1; i >= 0; i--) {
if (node.children[i].type !== 'comment') {
return getDeepestNode(node.children[i]);
}
}
return undefined;
}
exports.getDeepestNode = getDeepestNode;
function findNextWord(propertyValue, pos) {
let foundSpace = pos === -1;
let foundStart = false;
let foundEnd = false;
let newSelectionStart;
let newSelectionEnd;
while (pos < propertyValue.length - 1) {
pos++;
if (!foundSpace) {
if (propertyValue[pos] === ' ') {
foundSpace = true;
}
continue;
}
if (foundSpace && !foundStart && propertyValue[pos] === ' ') {
continue;
}
if (!foundStart) {
newSelectionStart = pos;
foundStart = true;
continue;
}
if (propertyValue[pos] === ' ') {
newSelectionEnd = pos;
foundEnd = true;
break;
}
}
if (foundStart && !foundEnd) {
newSelectionEnd = propertyValue.length;
}
return [newSelectionStart, newSelectionEnd];
}
exports.findNextWord = findNextWord;
function findPrevWord(propertyValue, pos) {
let foundSpace = pos === propertyValue.length;
let foundStart = false;
let foundEnd = false;
let newSelectionStart;
let newSelectionEnd;
while (pos > -1) {
pos--;
if (!foundSpace) {
if (propertyValue[pos] === ' ') {
foundSpace = true;
}
continue;
}
if (foundSpace && !foundEnd && propertyValue[pos] === ' ') {
continue;
}
if (!foundEnd) {
newSelectionEnd = pos + 1;
foundEnd = true;
continue;
}
if (propertyValue[pos] === ' ') {
newSelectionStart = pos + 1;
foundStart = true;
break;
}
}
if (foundEnd && !foundStart) {
newSelectionStart = 0;
}
return [newSelectionStart, newSelectionEnd];
}
exports.findPrevWord = findPrevWord;
function getEmmetConfiguration(syntax) {
const emmetConfig = coc_nvim_1.workspace.getConfiguration('emmet');
const syntaxProfiles = Object.assign({}, emmetConfig['syntaxProfiles'] || {});
const preferences = Object.assign({}, emmetConfig['preferences'] || {});
// jsx, xml and xsl syntaxes need to have self closing tags unless otherwise configured by user
if (syntax === 'jsx' || syntax === 'xml' || syntax === 'xsl') {
syntaxProfiles[syntax] = syntaxProfiles[syntax] || {};
if (typeof syntaxProfiles[syntax] === 'object'
&& !syntaxProfiles[syntax].hasOwnProperty('self_closing_tag') // Old Emmet format
&& !syntaxProfiles[syntax].hasOwnProperty('selfClosingStyle') // Emmet 2.0 format
) {
syntaxProfiles[syntax] = Object.assign({}, syntaxProfiles[syntax], { selfClosingStyle: 'xml' });
}
}
return {
preferences,
showExpandedAbbreviation: emmetConfig['showExpandedAbbreviation'],
showAbbreviationSuggestions: emmetConfig['showAbbreviationSuggestions'],
syntaxProfiles,
variables: emmetConfig['variables'],
excludeLanguages: emmetConfig['excludeLanguages'],
showSuggestionsAsSnippets: emmetConfig['showSuggestionsAsSnippets']
};
}
exports.getEmmetConfiguration = getEmmetConfiguration;
/**
* Itereates by each child, as well as nested child's children, in their order
* and invokes `fn` for each. If `fn` function returns `false`, iteration stops
*/
function iterateCSSToken(token, fn) {
for (let i = 0, il = token.size; i < il; i++) {
if (fn(token.item(i)) === false || iterateCSSToken(token.item(i), fn) === false) {
return false;
}
}
return true;
}
exports.iterateCSSToken = iterateCSSToken;
/**
* Returns `name` CSS property from given `rule`
*/
function getCssPropertyFromRule(rule, name) {
return rule.children.find(node => node.type === 'property' && node.name === name);
}
exports.getCssPropertyFromRule = getCssPropertyFromRule;
function getEmbeddedCssNodeIfAny(document, currentNode, position) {
if (!currentNode) {
return;
}
const currentHtmlNode = currentNode;
if (currentHtmlNode && currentHtmlNode.close) {
const innerRange = getInnerRange(currentHtmlNode);
if (innerRange && positionInRange(position, innerRange)) {
if (currentHtmlNode.name === 'style'
&& bufferStream_1.comparePosition(currentHtmlNode.open.end, position) < 0
&& bufferStream_1.comparePosition(currentHtmlNode.close.start, position) > 0) {
let buffer = new bufferStream_1.DocumentStreamReader(document, currentHtmlNode.open.end, vscode_languageserver_protocol_1.Range.create(currentHtmlNode.open.end, currentHtmlNode.close.start));
return css_parser_1.default(buffer);
}
}
}
return;
}
exports.getEmbeddedCssNodeIfAny = getEmbeddedCssNodeIfAny;
function isStyleAttribute(currentNode, position) {
if (!currentNode) {
return false;
}
const currentHtmlNode = currentNode;
const index = (currentHtmlNode.attributes || []).findIndex(x => x.name.toString() === 'style');
if (index === -1) {
return false;
}
const styleAttribute = currentHtmlNode.attributes[index];
return bufferStream_1.comparePosition(position, styleAttribute.value.start) >= 0 && bufferStream_1.comparePosition(position, styleAttribute.value.end) <= 0;
}
exports.isStyleAttribute = isStyleAttribute;
/***/ }),
/* 33 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defaultOptions", function() { return defaultOptions; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "match", function() { return match; });
/* harmony import */ var _emmetio_stream_reader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(34);
/* harmony import */ var _emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(35);
class Node {
constructor(stream, type, open, close) {
this.stream = stream;
this.type = type;
this.open = open;
this.close = close;
this.children = [];
this.parent = null;
}
/**
* Returns node name
* @return {String}
*/
get name() {
if (this.type === 'tag' && this.open) {
return this.open && this.open.name && this.open.name.value;
}
return '#' + this.type;
}
/**
* Returns attributes of current node
* @return {Array}
*/
get attributes() {
return this.open && this.open.attributes;
}
/**
* Returns nodes start position in stream
* @return {*}
*/
get start() {
return this.open && this.open.start;
}
/**
* Returns nodes start position in stream
* @return {*}
*/
get end() {
return this.close ? this.close.end : this.open && this.open.end;
}
get firstChild() {
return this.children[0];
}
get nextSibling() {
const ix = this.getIndex();
return ix !== -1 ? this.parent.children[ix + 1] : null;
}
get previousSibling() {
const ix = this.getIndex();
return ix !== -1 ? this.parent.children[ix - 1] : null;
}
/**
* Returns current elements index in parent list of child nodes
* @return {Number}
*/
getIndex() {
return this.parent ? this.parent.children.indexOf(this) : -1;
}
/**
* Adds given node as a child
* @param {Node} node
* @return {Node} Current node
*/
addChild(node) {
this.removeChild(node);
this.children.push(node);
node.parent = this;
return this;
}
/**
* Removes given node from current nodes child list
* @param {Node} node
* @return {Node} Current node
*/
removeChild(node) {
const ix = this.children.indexOf(node);
if (ix !== -1) {
this.children.splice(ix, 1);
node.parent = null;
}
return this;
}
}
/**
* A token factory method
* @param {StreamReader} stream
* @param {Point|Function} start Tokens start location or stream consumer
* @param {Point} [end] Tokens end location
* @return {Token}
*/
var token = function(stream, start, end) {
return typeof start === 'function'
? eatToken(stream, start)
: new Token(stream, start, end);
};
/**
* Consumes characters from given stream that matches `fn` call and returns it
* as token, if consumed
* @param {StreamReader} stream
* @param {Function} test
* @return {Token}
*/
function eatToken(stream, test) {
const start = stream.pos;
if (stream.eatWhile(test)) {
return new Token(stream, start, stream.pos);
}
stream.pos = start;
}
/**
* A structure describing text fragment in content stream
*/
class Token {
/**
* @param {ContentStreamReader} stream
* @param {Point} start Tokens start location in content stream
* @param {Point} end Tokens end location in content stream
*/
constructor(stream, start, end) {
this.stream = stream;
this.start = start != null ? start : stream.start;
this.end = end != null ? end : stream.pos;
this._value = null;
}
/**
* Returns token textual value
* NB implemented as getter to reduce unnecessary memory allocations for
* strings that not required
* @return {String}
*/
get value() {
if (this._value === null) {
const start = this.stream.start;
const end = this.stream.pos;
this.stream.start = this.start;
this.stream.pos = this.end;
this._value = this.stream.current();
this.stream.start = start;
this.stream.pos = end;
}
return this._value;
}
toString() {
return this.value;
}
valueOf() {
return `${this.value} [${this.start}; ${this.end}]`;
}
}
const LANGLE = 60;
const RANGLE = 62; // < and >
const LSQUARE = 91;
const RSQUARE = 93; // [ and ]
const LROUND = 40;
const RROUND = 41; // ( and )
const LCURLY = 123;
const RCURLY = 125; // { and }
const opt = { throws: true };
/**
* Consumes paired tokens (like `[` and `]`) with respect of nesting and embedded
* quoted values
* @param {StreamReader} stream
* @return {Token} A token with consumed paired character
*/
var eatPaired = function(stream) {
const start = stream.pos;
const consumed = Object(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["eatPair"])(stream, LANGLE, RANGLE, opt)
|| Object(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["eatPair"])(stream, LSQUARE, RSQUARE, opt)
|| Object(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["eatPair"])(stream, LROUND, RROUND, opt)
|| Object(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["eatPair"])(stream, LCURLY, RCURLY, opt);
if (consumed) {
return token(stream, start);
}
};
const SLASH$1 = 47; // /
const EQUALS = 61; // =
const RIGHT_ANGLE$1 = 62; // >
/**
* Consumes attributes from given stream
* @param {StreamReader} stream
* @return {Array} Array of consumed attributes
*/
var eatAttributes = function(stream) {
const result = [];
let name, value, attr;
while (!stream.eof()) {
stream.eatWhile(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["isSpace"]);
attr = { start: stream.pos };
// A name could be a regular name or expression:
// React-style <div {...props}>
// Angular-style <div [ng-for]>
if (attr.name = eatAttributeName(stream)) {
// Consumed attribute name. Can be an attribute with name
// or boolean attribute. The value can be React-like expression
if (stream.eat(EQUALS)) {
attr.value = eatAttributeValue(stream);
} else {
attr.boolean = true;
}
attr.end = stream.pos;
result.push(attr);
} else if (isTerminator(stream.peek())) {
// look for tag terminator in order to skip any other possible characters
// (maybe junk)
break;
} else {
stream.next();
}
}
return result;
};
/**
* Consumes attribute name from current location
* @param {StreamReader} stream
* @return {Token}
*/
function eatAttributeName(stream) {
return eatPaired(stream) || token(stream, isAttributeName);
}
/**
* Consumes attribute value from given location
* @param {StreamReader} stream
* @return {Token}
*/
function eatAttributeValue(stream) {
const start = stream.pos;
if (Object(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["eatQuoted"])(stream)) {
// Should return token that points to unquoted value.
// Use stream readers public API to traverse instead of direct
// manipulation
const current = stream.pos;
let valueStart, valueEnd;
stream.pos = start;
stream.next();
valueStart = stream.start = stream.pos;
stream.pos = current;
stream.backUp(1);
valueEnd = stream.pos;
const result = token(stream, valueStart, valueEnd);
stream.pos = current;
return result;
}
return eatPaired(stream) || eatUnquoted(stream);
}
/**
* Check if given code belongs to attribute name.
* NB some custom HTML variations allow non-default values in name, like `*ngFor`
* @param {Number} code
* @return {Boolean}
*/
function isAttributeName(code) {
return code !== EQUALS && !isTerminator(code) && !Object(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["isSpace"])(code);
}
/**
* Check if given code is tag terminator
* @param {Number} code
* @return {Boolean}
*/
function isTerminator(code) {
return code === RIGHT_ANGLE$1 || code === SLASH$1;
}
/**
* Eats unquoted value from stream
* @param {StreamReader} stream
* @return {Token}
*/
function eatUnquoted(stream) {
return token(stream, isUnquoted);
}
/**
* Check if given character code is valid unquoted value
* @param {Number} code
* @return {Boolean}
*/
function isUnquoted(code) {
return !isNaN(code) && !Object(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["isQuote"])(code) && !Object(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["isSpace"])(code) && !isTerminator(code);
}
const DASH = 45; // -
const DOT = 46; // .
const SLASH = 47; // /
const COLON = 58; // :
const LEFT_ANGLE = 60; // <
const RIGHT_ANGLE = 62; // >
const UNDERSCORE = 95; // _
/**
* Parses tag definition (open or close tag) from given stream state
* @param {StreamReader} stream Content stream reader
* @return {Object}
*/
var tag = function(stream) {
const start = stream.pos;
if (stream.eat(LEFT_ANGLE)) {
const model = { type: stream.eat(SLASH) ? 'close' : 'open' };
if (model.name = eatTagName(stream)) {
if (model.type !== 'close') {
model.attributes = eatAttributes(stream);
stream.eatWhile(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["isSpace"]);
model.selfClosing = stream.eat(SLASH);
}
if (stream.eat(RIGHT_ANGLE)) {
// tag properly closed
return Object.assign(token(stream, start), model);
}
}
}
// invalid tag, revert to original position
stream.pos = start;
return null;
};
/**
* Eats HTML identifier (tag or attribute name) from given stream
* @param {StreamReader} stream
* @return {Token}
*/
function eatTagName(stream) {
return token(stream, isTagName);
}
/**
* Check if given character code can be used as HTML/XML tag name
* @param {Number} code
* @return {Boolean}
*/
function isTagName(code) {
return Object(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["isAlphaNumeric"])(code)
|| code === COLON // colon is used for namespaces
|| code === DOT // in rare cases declarative tag names may have dots in names
|| code === DASH
|| code === UNDERSCORE;
}
/**
* Eats array of character codes from given stream
* @param {StreamReader} stream
* @param {Number[]} codes Array of character codes
* @return {Boolean}
*/
function eatArray(stream, codes) {
const start = stream.pos;
for (let i = 0; i < codes.length; i++) {
if (!stream.eat(codes[i])) {
stream.pos = start;
return false;
}
}
stream.start = start;
return true;
}
/**
* Consumes section from given string which starts with `open` character codes
* and ends with `close` character codes
* @param {StreamReader} stream
* @param {Number[]} open
* @param {Number[]} close
* @return {Boolean} Returns `true` if section was consumed
*/
function eatSection(stream, open, close, allowUnclosed) {
const start = stream.pos;
if (eatArray(stream, open)) {
// consumed `<!--`, read next until we find ending part or reach the end of input
while (!stream.eof()) {
if (eatArray(stream, close)) {
return true;
}
stream.next();
}
// unclosed section is allowed
if (allowUnclosed) {
return true;
}
stream.pos = start;
return false;
}
// unable to find section, revert to initial position
stream.pos = start;
return null;
}
/**
* Converts given string into array of character codes
* @param {String} str
* @return {Number[]}
*/
function toCharCodes(str) {
return str.split('').map(ch => ch.charCodeAt(0));
}
const open = toCharCodes('<!--');
const close = toCharCodes('-->');
/**
* Consumes HTML comment from given stream
* @param {StreamReader} stream
* @return {Token}
*/
var comment = function(stream) {
const start = stream.pos;
if (eatSection(stream, open, close, true)) {
const result = token(stream, start);
result.type = 'comment';
return result;
}
return null;
};
const open$1 = toCharCodes('<![CDATA[');
const close$1 = toCharCodes(']]>');
/**
* Consumes CDATA from given stream
* @param {StreamReader} stream
* @return {Token}
*/
var cdata = function(stream) {
const start = stream.pos;
if (eatSection(stream, open$1, close$1, true)) {
const result = token(stream, start);
result.type = 'cdata';
return result;
}
return null;
};
const defaultOptions = {
/**
* Expect XML content in searching content. It alters how should-be-empty
* elements are treated: for example, in XML mode parser will try to locate
* closing pair for `<br>` tag
* @type {Boolean}
*/
xml: false,
special: ['script', 'style'],
/**
* List of elements that should be treated as empty (e.g. without closing tag)
* in non-XML syntax
* @type {Array}
*/
empty: ['img', 'meta', 'link', 'br', 'base', 'hr', 'area', 'wbr','col', 'embed', 'input', 'param', 'source', 'track']
};
/**
* Parses given content into a DOM-like structure
* @param {String|StreamReader} content
* @param {Object} options
* @return {Node}
*/
function parse(content, options) {
options = Object.assign({}, defaultOptions, options);
const stream = typeof content === 'string'
? new _emmetio_stream_reader__WEBPACK_IMPORTED_MODULE_0__["default"](content)
: content;
const root = new Node(stream, 'root');
const empty = new Set(options.empty);
const special = options.special.reduce(
(map, name) => map.set(name, toCharCodes(`</${name}>`)), new Map());
const isEmpty = (token, name) =>
token.selfClosing || (!options.xml && empty.has(name));
let m, node, name, stack = [root];
while (!stream.eof()) {
if (m = match(stream)) {
name = getName(m);
if (m.type === 'open') {
// opening tag
node = new Node(stream, 'tag', m);
last(stack).addChild(node);
if (special.has(name)) {
node.close = consumeSpecial(stream, special.get(name));
} else if (!isEmpty(m, name)) {
stack.push(node);
}
} else if (m.type === 'close') {
// closing tag, find its matching opening tag
for (let i = stack.length - 1; i > 0; i--) {
if (stack[i].name.toLowerCase() === name) {
stack[i].close = m;
stack = stack.slice(0, i);
break;
}
}
} else {
last(stack).addChild(new Node(stream, m.type, m));
}
} else {
stream.next();
}
}
return root;
}
/**
* Matches known token in current state of given stream
* @param {ContentStreamReader} stream
* @return {Token}
*/
function match(stream) {
// fast-path optimization: check for `<` code
if (stream.peek() === 60 /* < */) {
return comment(stream) || cdata(stream) || tag(stream);
}
}
/**
* @param {StreamReader} stream
* @param {Number[]} codes
* @return {Token}
*/
function consumeSpecial(stream, codes) {
const start = stream.pos;
let m;
while (!stream.eof()) {
if (eatArray(stream, codes)) {
stream.pos = stream.start;
return tag(stream);
}
stream.next();
}
stream.pos = start;
return null;
}
/**
* Returns name of given matched token
* @param {Token} tag
* @return {String}
*/
function getName(tag$$1) {
return tag$$1.name ? tag$$1.name.value.toLowerCase() : `#${tag$$1.type}`;
}
function last(arr) {
return arr[arr.length - 1];
}
/* harmony default export */ __webpack_exports__["default"] = (parse);
/***/ }),
/* 34 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/**
* A streaming, character code-based string reader
*/
class StreamReader {
constructor(string, start, end) {
if (end == null && typeof string === 'string') {
end = string.length;
}
this.string = string;
this.pos = this.start = start || 0;
this.end = end;
}
/**
* Returns true only if the stream is at the end of the file.
* @returns {Boolean}
*/
eof() {
return this.pos >= this.end;
}
/**
* Creates a new stream instance which is limited to given `start` and `end`
* range. E.g. its `eof()` method will look at `end` property, not actual
* stream end
* @param {Point} start
* @param {Point} end
* @return {StreamReader}
*/
limit(start, end) {
return new this.constructor(this.string, start, end);
}
/**
* Returns the next character code in the stream without advancing it.
* Will return NaN at the end of the file.
* @returns {Number}
*/
peek() {
return this.string.charCodeAt(this.pos);
}
/**
* Returns the next character in the stream and advances it.
* Also returns <code>undefined</code> when no more characters are available.
* @returns {Number}
*/
next() {
if (this.pos < this.string.length) {
return this.string.charCodeAt(this.pos++);
}
}
/**
* `match` can be a character code or a function that takes a character code
* and returns a boolean. If the next character in the stream 'matches'
* the given argument, it is consumed and returned.
* Otherwise, `false` is returned.
* @param {Number|Function} match
* @returns {Boolean}
*/
eat(match) {
const ch = this.peek();
const ok = typeof match === 'function' ? match(ch) : ch === match;
if (ok) {
this.next();
}
return ok;
}
/**
* Repeatedly calls <code>eat</code> with the given argument, until it
* fails. Returns <code>true</code> if any characters were eaten.
* @param {Object} match
* @returns {Boolean}
*/
eatWhile(match) {
const start = this.pos;
while (!this.eof() && this.eat(match)) {}
return this.pos !== start;
}
/**
* Backs up the stream n characters. Backing it up further than the
* start of the current token will cause things to break, so be careful.
* @param {Number} n
*/
backUp(n) {
this.pos -= (n || 1);
}
/**
* Get the string between the start of the current token and the
* current stream position.
* @returns {String}
*/
current() {
return this.substring(this.start, this.pos);
}
/**
* Returns substring for given range
* @param {Number} start
* @param {Number} [end]
* @return {String}
*/
substring(start, end) {
return this.string.slice(start, end);
}
/**
* Creates error object with current stream state
* @param {String} message
* @return {Error}
*/
error(message) {
const err = new Error(`${message} at char ${this.pos + 1}`);
err.originalMessage = message;
err.pos = this.pos;
err.string = this.string;
return err;
}
}
/* harmony default export */ __webpack_exports__["default"] = (StreamReader);
/***/ }),
/* 35 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "eatQuoted", function() { return eatQuoted; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isQuote", function() { return isQuote; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isAlpha", function() { return isAlpha; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isNumber", function() { return isNumber; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isAlphaNumeric", function() { return isAlphaNumeric; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isSpace", function() { return isSpace; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isWhiteSpace", function() { return isWhiteSpace; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "eatPair", function() { return eatPair; });
/**
* Methods for consuming quoted values
*/
const SINGLE_QUOTE = 39; // '
const DOUBLE_QUOTE = 34; // "
const defaultOptions = {
escape: 92, // \ character
throws: false
};
/**
* Consumes 'single' or "double"-quoted string from given string, if possible
* @param {StreamReader} stream
* @param {Number} options.escape A character code of quote-escape symbol
* @param {Boolean} options.throws Throw error if quotes string cant be properly consumed
* @return {Boolean} `true` if quoted string was consumed. The contents
* of quoted string will be availabe as `stream.current()`
*/
var eatQuoted = function(stream, options) {
options = options ? Object.assign({}, defaultOptions, options) : defaultOptions;
const start = stream.pos;
const quote = stream.peek();
if (stream.eat(isQuote)) {
while (!stream.eof()) {
switch (stream.next()) {
case quote:
stream.start = start;
return true;
case options.escape:
stream.next();
break;
}
}
// If were here then stream wasnt properly consumed.
// Revert stream and decide what to do
stream.pos = start;
if (options.throws) {
throw stream.error('Unable to consume quoted string');
}
}
return false;
};
function isQuote(code) {
return code === SINGLE_QUOTE || code === DOUBLE_QUOTE;
}
/**
* Check if given code is a number
* @param {Number} code
* @return {Boolean}
*/
function isNumber(code) {
return code > 47 && code < 58;
}
/**
* Check if given character code is alpha code (letter through A to Z)
* @param {Number} code
* @param {Number} [from]
* @param {Number} [to]
* @return {Boolean}
*/
function isAlpha(code, from, to) {
from = from || 65; // A
to = to || 90; // Z
code &= ~32; // quick hack to convert any char code to uppercase char code
return code >= from && code <= to;
}
/**
* Check if given character code is alpha-numeric (letter through A to Z or number)
* @param {Number} code
* @return {Boolean}
*/
function isAlphaNumeric(code) {
return isNumber(code) || isAlpha(code);
}
function isWhiteSpace(code) {
return code === 32 /* space */
|| code === 9 /* tab */
|| code === 160; /* non-breaking space */
}
/**
* Check if given character code is a space
* @param {Number} code
* @return {Boolean}
*/
function isSpace(code) {
return isWhiteSpace(code)
|| code === 10 /* LF */
|| code === 13; /* CR */
}
const defaultOptions$1 = {
escape: 92, // \ character
throws: false
};
/**
* Eats paired characters substring, for example `(foo)` or `[bar]`
* @param {StreamReader} stream
* @param {Number} open Character code of pair openinig
* @param {Number} close Character code of pair closing
* @param {Object} [options]
* @return {Boolean} Returns `true` if chacarter pair was successfully
* consumed, its content will be available as `stream.current()`
*/
function eatPair(stream, open, close, options) {
options = options ? Object.assign({}, defaultOptions$1, options) : defaultOptions$1;
const start = stream.pos;
if (stream.eat(open)) {
let stack = 1, ch;
while (!stream.eof()) {
if (eatQuoted(stream, options)) {
continue;
}
ch = stream.next();
if (ch === open) {
stack++;
} else if (ch === close) {
stack--;
if (!stack) {
stream.start = start;
return true;
}
} else if (ch === options.escape) {
stream.next();
}
}
// If were here then paired character cant be consumed
stream.pos = start;
if (options.throws) {
throw stream.error(`Unable to find matching pair for ${String.fromCharCode(open)}`);
}
}
return false;
}
/***/ }),
/* 36 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "lexer", function() { return lexer; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Token", function() { return Token; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "any", function() { return any; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "selector", function() { return selector; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "value", function() { return value; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "keyword", function() { return keyword; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "variable", function() { return variable; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "formatting", function() { return formatting; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "comment", function() { return comment; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "whitespace", function() { return whitespace; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ident", function() { return ident; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "string", function() { return string; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "url", function() { return url; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "interpolation", function() { return interpolation; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "backtick", function() { return backtick; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseMediaExpression", function() { return parseMediaExpression; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parsePropertyName", function() { return parsePropertyName; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parsePropertyValue", function() { return parsePropertyValue; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseSelector", function() { return parseSelector; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createProperty", function() { return createProperty; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createRule", function() { return createRule; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createAtRule", function() { return createAtRule; });
/* harmony import */ var _emmetio_stream_reader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(34);
/* harmony import */ var _emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(35);
/**
* Abstract container that contains nested nodes or other containers
*/
class Node {
constructor(type) {
this.type = type;
this.children = [];
this.parent = null;
}
get firstChild() {
return this.children[0];
}
get nextSibling() {
const ix = this.index();
return ix !== -1 ? this.parent.children[ix + 1] : null;
}
get previousSibling() {
const ix = this.index();
return ix !== -1 ? this.parent.children[ix - 1] : null;
}
/**
* Returns current elements index in parent list of child nodes
* @return {Number}
*/
index() {
return this.parent ? this.parent.children.indexOf(this) : -1;
}
/**
* Adds given node as a child
* @param {Node} node
* @return {Node} Current node
*/
add(node) {
if (node) {
node.remove();
this.children.push(node);
node.parent = this;
}
return this;
}
/**
* Removes current node from its parent
* @return {Node} Current node
*/
remove() {
if (this.parent) {
const ix = this.index();
if (ix !== -1) {
this.parent.children.splice(ix, 1);
this.parent = null;
}
}
return this;
}
}
class Stylesheet extends Node {
constructor() {
super('stylesheet');
this.comments = [];
}
/**
* Returns nodes start position in stream
* @return {*}
*/
get start() {
const node = this.firstChild;
return node && node.start;
}
/**
* Returns nodes end position in stream
* @return {*}
*/
get end() {
const node = this.children[this.children.length - 1];
return node && node.end;
}
/**
* Adds comment token into a list.
* This somewhat awkward feature is required to properly detect comment
* ranges. Specifically, in Atom: its API provides scopes limited to current
* line only
* @param {Token} token
*/
addComment(token) {
this.comments.push(token);
}
}
/**
* Removes tokens that matches given criteria from start and end of given list
* @param {Token[]} tokens
* @return {Token[]}
*/
function trimTokens(tokens) {
tokens = tokens.slice();
let len;
while (len !== tokens.length) {
len = tokens.length;
if (isFormattingToken(tokens[0])) {
tokens.shift();
}
if (isFormattingToken(last(tokens))) {
tokens.pop();
}
}
return tokens;
}
/**
* Trims formatting tokens (whitespace and comments) from the beginning and end
* of given token list
* @param {Token[]} tokens
* @return {Token[]}
*/
function trimFormatting(tokens) {
return trimTokens(tokens, isFormattingToken);
}
/**
* Check if given token is a formatting one (whitespace or comment)
* @param {Token} token
* @return {Boolean}
*/
function isFormattingToken(token) {
const type = token && token.type;
return type === 'whitespace' || type === 'comment';
}
/**
* Consumes string char-by-char from given stream
* @param {StreamReader} stream
* @param {String} string
* @return {Boolean} Returns `true` if string was completely consumed
*/
function eatString(stream, string) {
const start = stream.pos;
for (let i = 0, il = string.length; i < il; i++) {
if (!stream.eat(string.charCodeAt(i))) {
stream.pos = start;
return false;
}
}
return true;
}
function consume(stream, match) {
const start = stream.pos;
if (stream.eat(match)) {
stream.start = start;
return true;
}
return false;
}
function consumeWhile(stream, match) {
const start = stream.pos;
if (stream.eatWhile(match)) {
stream.start = start;
return true;
}
return false;
}
function last(arr) {
return arr[arr.length - 1];
}
function valueOf(token) {
return token && token.valueOf();
}
/**
* A structure describing text fragment in content stream. It may contain
* other sub-fragments (also tokens) that represent current fragments logical
* parts
*/
class Token {
/**
* @param {StreamReader} stream
* @param {String} type Token type
* @param {Object} [start] Tokens start position in `stream`
* @param {Object} [end] Tokens end position in `stream`
*/
constructor(stream, type, start, end) {
this.stream = stream;
this.start = start != null ? start : stream.start;
this.end = end != null ? end : stream.pos;
this.type = type;
this._props = null;
this._value = null;
this._items = null;
}
get size() {
return this._items ? this._items.length : 0;
}
get items() {
return this._items;
}
clone(start, end) {
return new this.constructor(this.stream, this.type,
start != null ? start : this.start,
end != null ? end : this.end);
}
add(item) {
if (Array.isArray(item)) {
for (let i = 0, il = item.length; i < il; i++) {
this.add(item[i]);
}
} else if (item) {
if (!this._items) {
this._items = [item];
} else {
this._items.push(item);
}
}
return this;
}
remove(item) {
if (this._items) {
const ix = this._items.indexOf(item);
if (ix !== -1 ) {
this._items.splice(ix, 1);
}
}
return this;
}
item(i) {
const size = this.size;
return this._items && this._items[(size + i) % size];
}
limit() {
return this.stream.limit(this.start, this.end);
}
slice(from, to) {
const token = this.clone();
const items = this._items && this._items.slice(from, to);
if (items && items.length) {
token.start = items[0].start;
token.end = items[items.length - 1].end;
token.add(items);
} else if (items) {
// Empty token
token.start = token.end;
}
return token;
}
property(name, value) {
if (typeof value !== 'undefined') {
// set property value
if (!this._props) {
this._props = {};
}
this._props[name] = value;
}
return this._props && this._props[name];
}
/**
* Returns token textual representation
* @return {String}
*/
toString() {
return `${this.valueOf()} [${this.start}, ${this.end}] (${this.type})`;
}
valueOf() {
if (this._value === null) {
this._value = this.stream.substring(this.start, this.end);
}
return this._value;
}
}
const COMMA = 44; // ,
const PROP_DELIMITER$1 = 58; // :
const PROP_TERMINATOR$1 = 59; // ;
const RULE_START$1 = 123; // {
const RULE_END$1 = 125; // }
const types = new Map()
.set(COMMA, 'comma')
.set(PROP_DELIMITER$1, 'propertyDelimiter')
.set(PROP_TERMINATOR$1, 'propertyTerminator')
.set(RULE_START$1, 'ruleStart')
.set(RULE_END$1, 'ruleEnd');
/**
* Consumes separator token from given string
*/
function separator(stream) {
if (isSeparator(stream.peek())) {
const start = stream.pos;
const type = types.get(stream.next());
const token = new Token(stream, 'separator', start);
token.property('type', type);
return token;
}
}
function isSeparator(code) {
return code === COMMA
|| code === PROP_DELIMITER$1 || code === PROP_TERMINATOR$1
|| code === RULE_START$1 || code === RULE_END$1;
}
const ARGUMENTS_START = 40; // (
const ARGUMENTS_END = 41; // )
var args = function(stream, tokenConsumer) {
if (stream.peek() === ARGUMENTS_START) {
const start = stream.pos;
stream.next();
const tokens = [];
let t;
// in LESS, its possible to separate arguments list either by `;` or `,`.
// In first case, we should keep comma-separated item as a single argument
let usePropTerminator = false;
while (!stream.eof()) {
if (isUnexpectedTerminator(stream.peek()) || stream.eat(ARGUMENTS_END)) {
break;
}
t = tokenConsumer(stream);
if (!t) {
break;
}
if (isSemicolonSeparator(t)) {
usePropTerminator = true;
}
tokens.push(t);
}
stream.start = start;
return createArgumentList(stream, tokens, usePropTerminator);
}
};
function isUnexpectedTerminator(code) {
return code === RULE_START$1 || code === RULE_END$1;
}
function createArgumentList(stream, tokens, usePropTerminator) {
const argsToken = new Token(stream, 'arguments');
const isSeparator = usePropTerminator ? isSemicolonSeparator : isCommaSeparator;
let arg = [];
for (let i = 0, il = tokens.length, token; i < il; i++) {
token = tokens[i];
if (isSeparator(token)) {
argsToken.add(createArgument(stream, arg) || createEmptyArgument(stream, token.start));
arg.length = 0;
} else {
arg.push(token);
}
}
if (arg.length) {
argsToken.add(createArgument(stream, arg));
}
return argsToken;
}
function createArgument(stream, tokens) {
tokens = trimFormatting(tokens);
if (tokens.length) {
const arg = new Token(stream, 'argument', tokens[0].start, last(tokens).end);
for (let i = 0; i < tokens.length; i++) {
arg.add(tokens[i]);
}
return arg;
}
}
function createEmptyArgument(stream, pos) {
const token = new Token(stream, 'argument', pos, pos);
token.property('empty', true);
return token;
}
function isCommaSeparator(token) {
return token.property('type') === 'comma';
}
function isSemicolonSeparator(token) {
return token.property('type') === 'propertyTerminator';
}
const HYPHEN = 45;
const UNDERSCORE = 95;
function ident(stream) {
return eatIdent(stream) && new Token(stream, 'ident');
}
function eatIdent(stream) {
const start = stream.pos;
stream.eat(HYPHEN);
if (stream.eat(isIdentStart)) {
stream.eatWhile(isIdent);
stream.start = start;
return true;
}
stream.pos = start;
return false;
}
function isIdentStart(code) {
return code === UNDERSCORE || code === HYPHEN || Object(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["isAlpha"])(code) || code >= 128;
}
function isIdent(code) {
return Object(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["isNumber"])(code) || isIdentStart(code);
}
function prefixed(stream, tokenType, prefix, body, allowEmptyBody) {
const start = stream.pos;
if (stream.eat(prefix)) {
const bodyToken = body(stream, start);
if (bodyToken || allowEmptyBody) {
stream.start = start;
return new Token(stream, tokenType, start).add(bodyToken);
}
}
stream.pos = start;
}
const AT = 64; // @
/**
* Consumes at-keyword from given stream
*/
function atKeyword(stream) {
return prefixed(stream, 'at-keyword', AT, ident);
}
const HASH = 35; // #
const AT$1 = 64; // @
/**
* Consumes interpolation token, e.g. `#{expression}`
* @param {StreamReader} stream
* @param {Function} tokenConsumer
* @return {Token}
*/
function interpolation(stream, tokenConsumer) {
const start = stream.pos;
tokenConsumer = tokenConsumer || defaultTokenConsumer;
if ((stream.eat(HASH) || stream.eat(AT$1)) && stream.eat(RULE_START$1)) {
const container = new Token(stream, 'interpolation', start);
let stack = 1, token;
while (!stream.eof()) {
if (stream.eat(RULE_START$1)) {
stack++;
} else if (stream.eat(RULE_END$1)) {
stack--;
if (!stack) {
container.end = stream.pos;
return container;
}
} else if (token = tokenConsumer(stream)) {
container.add(token);
} else {
break;
}
}
}
stream.pos = start;
}
function eatInterpolation(stream) {
const start = stream.pos;
if ((stream.eat(HASH) || stream.eat(AT$1)) && Object(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["eatPair"])(stream, RULE_START$1, RULE_END$1)) {
stream.start = start;
return true;
}
stream.pos = start;
return false;
}
function defaultTokenConsumer(stream) {
const start = stream.pos;
while (!stream.eof()) {
if (stream.peek() === RULE_END$1) {
break;
}
eatString$1(stream) || stream.next();
}
if (start !== stream.pos) {
return new Token(stream, 'expression', start);
}
}
/**
* Consumes quoted string from current string and returns token with consumed
* data or `null`, if string wasnt consumed
* @param {StreamReader} stream
* @return {StringToken}
*/
function string(stream) {
return eatString$1(stream, true);
}
function eatString$1(stream, asToken) {
let ch = stream.peek(), pos, tokens, token;
if (Object(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["isQuote"])(ch)) {
stream.start = stream.pos;
stream.next();
const quote = ch;
const valueStart = stream.pos;
while (!stream.eof()) {
pos = stream.pos;
if (stream.eat(quote) || stream.eat(isNewline)) {
// found end of string or newline without preceding '\',
// which is not allowed (dont throw error, for now)
break;
} else if (stream.eat(92 /* \ */)) {
// backslash allows newline in string
stream.eat(isNewline);
} else if (asToken && (token = interpolation(stream))) {
if (!tokens) {
tokens = [token];
} else {
tokens.push(token);
}
}
stream.next();
}
// Either reached EOF or explicitly stopped at string end
// NB use extra `asToken` param to return boolean instead of token to reduce
// memory allocations and improve performance
if (asToken) {
const token = new Token(stream, 'string');
const inner = new Token(stream, 'unquoted', valueStart, pos);
inner.add(tokens);
token.add(inner);
token.property('quote', quote);
return token;
}
return true;
}
return false;
}
function isNewline(code) {
return code === 10 /* LF */ || code === 13 /* CR */;
}
const ASTERISK = 42;
const SLASH = 47;
/**
* Consumes comment from given stream: either multi-line or single-line
* @param {StreamReader} stream
* @return {CommentToken}
*/
var comment = function(stream) {
return singleLineComment(stream) || multiLineComment(stream);
};
function singleLineComment(stream) {
if (eatSingleLineComment(stream)) {
const token = new Token(stream, 'comment');
token.property('type', 'single-line');
return token;
}
}
function multiLineComment(stream) {
if (eatMultiLineComment(stream)) {
const token = new Token(stream, 'comment');
token.property('type', 'multiline');
return token;
}
}
function eatComment(stream) {
return eatSingleLineComment(stream) || eatMultiLineComment(stream);
}
function eatSingleLineComment(stream) {
const start = stream.pos;
if (stream.eat(SLASH) && stream.eat(SLASH)) {
// single-line comment, consume till the end of line
stream.start = start;
while (!stream.eof()) {
if (isLineBreak(stream.next())) {
break;
}
}
return true;
}
stream.pos = start;
return false;
}
function eatMultiLineComment(stream) {
const start = stream.pos;
if (stream.eat(SLASH) && stream.eat(ASTERISK)) {
while (!stream.eof()) {
if (stream.next() === ASTERISK && stream.eat(SLASH)) {
break;
}
}
stream.start = start;
return true;
}
stream.pos = start;
return false;
}
function isLineBreak(code) {
return code === 10 /* LF */ || code === 13 /* CR */;
}
/**
* Consumes white-space tokens from given stream
*/
function whitespace(stream) {
return eatWhitespace(stream) && new Token(stream, 'whitespace');
}
function eatWhitespace(stream) {
return consumeWhile(stream, _emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["isSpace"]);
}
const ATTR_START = 91; // [
const ATTR_END = 93; // ]
/**
* Consumes attribute from given string, e.g. value between [ and ]
* @param {StreamReader} stream
* @return {AttributeToken}
*/
function eatAttribuite(stream) {
const start = stream.pos;
if (stream.eat(ATTR_START)) {
skip(stream);
const name = ident(stream);
skip(stream);
const op = operator(stream);
skip(stream);
const value = string(stream) || ident(stream);
skip(stream);
stream.eat(ATTR_END);
return new Token(stream, 'attribute', start).add(name).add(op).add(value);
}
}
function skip(stream) {
while (!stream.eof()) {
if (!eatWhitespace(stream) && !eatComment(stream)) {
return true;
}
}
}
function operator(stream) {
return consumeWhile(stream, isOperator) && new Token(stream, 'operator');
}
function isOperator(code) {
return code === 126 /* ~ */
|| code === 124 /* | */
|| code === 94 /* ^ */
|| code === 36 /* $ */
|| code === 42 /* * */
|| code === 61; /* = */
}
const BACKTICK = 96; // `
/**
* Consumes backtick token, e.g. `...`
* @param {StreamReader} stream
* @param {Function} tokenConsumer
* @return {Token}
*/
function backtick(stream) {
if (eatBacktick(stream)) {
return new Token(stream, 'backtick');
}
}
function eatBacktick(stream) {
const start = stream.pos;
if (Object(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["eatPair"])(stream, BACKTICK, BACKTICK)) {
stream.start = start;
return true;
}
return false;
}
const CLASS = 46; // .
/**
* Consumes class fragment from given stream, e.g. `.foo`
* @param {StreamReader} stream
* @return {ClassToken}
*/
function className(stream) {
return prefixed(stream, 'class', CLASS, ident);
}
const ADJACENT_SIBLING = 43; // +
const GENERAL_SIBLING = 126; // ~
const CHILD = 62; // >
const NESTING = 38; // &
const types$1 = {
[ADJACENT_SIBLING]: 'adjacentSibling',
[GENERAL_SIBLING]: 'generalSibling',
[CHILD]: 'child',
[NESTING]: 'nesting'
};
/**
* Consumes combinator token from given string
*/
var combinator = function(stream) {
if (isCombinator(stream.peek())) {
const start = stream.pos;
const type = types$1[stream.next()];
const token = new Token(stream, 'combinator', start);
token.property('type', type);
return token;
}
};
function isCombinator(code) {
return code === ADJACENT_SIBLING || code === GENERAL_SIBLING
|| code === NESTING || code === CHILD;
}
const HASH$1 = 35;
function hash(stream) {
return prefixed(stream, 'hash', HASH$1, hashValue, true);
}
function hashValue(stream) {
if (eatHashValue(stream)) {
return new Token(stream, 'hash-value');
}
}
function eatHashValue(stream) {
return consumeWhile(stream, isHashValue);
}
function isHashValue(code) {
return Object(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["isNumber"])(code) || Object(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["isAlpha"])(code, 65 /* A */, 70 /* F */)
|| code === 95 /* _ */ || code === 45 /* - */
|| code > 128; /* non-ASCII */
}
const ID = 35; // #
/**
* Consumes id fragment from given stream, e.g. `#foo`
* @param {StreamReader} stream
* @return {Token}
*/
function id(stream) {
return prefixed(stream, 'id', ID, ident);
}
const IMPORTANT = 33; // !
/**
* Consumes !important token
* @param {StreamReader} stream
* @return {Token}
*/
function important(stream) {
return prefixed(stream, 'important', IMPORTANT, ident);
}
const DOT = 46; // .
/**
* Consumes number from given string, e.g. `10px`
* @param {StreamReader} stream
* @return {NumberToken}
*/
function number(stream) {
if (eatNumericPart(stream)) {
const start = stream.start;
const num = new Token(stream, 'value');
const unit = eatUnitPart(stream) ? new Token(stream, 'unit') : null;
return new Token(stream, 'number', start).add(num).add(unit);
}
}
function eatNumericPart(stream) {
const start = stream.pos;
stream.eat(isOperator$1);
if (stream.eatWhile(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["isNumber"])) {
stream.start = start;
const decimalEnd = stream.pos;
if (!(stream.eat(DOT) && stream.eatWhile(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["isNumber"]))) {
stream.pos = decimalEnd;
}
return true;
} else if (stream.eat(DOT) && stream.eatWhile(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["isNumber"])) {
stream.start = start;
return true;
}
// TODO eat exponent part
stream.pos = start;
return false;
}
function eatUnitPart(stream) {
return eatIdent(stream) || eatPercent(stream);
}
function eatPercent(stream) {
return consume(stream, 37 /* % */);
}
function isOperator$1(code) {
return code === 45 /* - */ || code === 43 /* + */;
}
const NOT = 33; // !
const MULTIPLY = 42; // *
const PLUS = 43; // +
const MINUS = 45; // -
const DIVIDE = 47; // /
const LESS_THAN = 60; // <
const EQUALS = 61; // =
const GREATER_THAN = 62; // <
function operator$1(stream) {
return eatOperator(stream) && new Token(stream, 'operator');
}
function eatOperator(stream) {
if (consume(stream, isEquality)) {
stream.eatWhile(EQUALS);
return true;
} else if (consume(stream, isOperator$2)) {
return true;
}
return false;
}
function isEquality(code) {
return code === NOT || code === LESS_THAN || code === EQUALS || code === GREATER_THAN;
}
function isOperator$2(code) {
return code === MULTIPLY || code === PLUS || code === MINUS || code === DIVIDE
|| isEquality(code);
}
const PSEUDO = 58; // :
/**
* Consumes pseudo-selector from given stream
*/
var pseudo = function(stream) {
const start = stream.pos;
if (stream.eatWhile(PSEUDO)) {
const name = ident(stream);
if (name) {
return new Token(stream, 'pseudo', start).add(name);
}
}
stream.pos = start;
};
/**
* Consumes unquoted value from given stream
* @param {StreamReader} stream
* @return {UnquotedToken}
*/
var unquoted = function(stream) {
return eatUnquoted(stream) && new Token(stream, 'unquoted');
};
function eatUnquoted(stream) {
return consumeWhile(stream, isUnquoted);
}
function isUnquoted(code) {
return !isNaN(code) && !Object(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["isQuote"])(code) && !Object(_emmetio_stream_reader_utils__WEBPACK_IMPORTED_MODULE_1__["isSpace"])(code)
&& code !== 40 /* ( */ && code !== 41 /* ) */ && code !== 92 /* \ */
&& !isNonPrintable(code);
}
function isNonPrintable(code) {
return (code >= 0 && code <= 8) || code === 11
|| (code >= 14 && code <= 31) || code === 127;
}
/**
* Consumes URL token from given stream
* @param {StreamReader} stream
* @return {Token}
*/
function url(stream) {
const start = stream.pos;
if (eatString(stream, 'url(')) {
eatWhitespace(stream);
const value = string(stream) || unquoted(stream);
eatWhitespace(stream);
stream.eat(41); // )
return new Token(stream, 'url', start).add(value);
}
stream.pos = start;
}
function eatUrl(stream) {
const start = stream.pos;
if (eatString(stream, 'url(')) {
eatWhitespace(stream);
eatString$1(stream) || eatUnquoted(stream);
eatWhitespace(stream);
stream.eat(41); // )
stream.start = start;
return true;
}
stream.pos = start;
return false;
}
const VARIABLE = 36; // $
/**
* Consumes SCSS variable from given stream
*/
function variable(stream) {
return prefixed(stream, 'variable', VARIABLE, variableName);
}
function variableName(stream) {
if (eatVariableName(stream)) {
return new Token(stream, 'name');
}
}
function eatVariableName(stream) {
return consumeWhile(stream, isVariableName);
}
function isVariableName(code) {
return code === VARIABLE || isIdent(code);
}
/**
* Group tokens by commonly used context
*/
function consumeToken(stream) {
const _token = any(stream) || args(stream, consumeToken);
if (_token && _token.type === 'ident') {
const _args = args(stream, consumeToken);
if (_args) {
// An identifier followed by arguments function call
return new Token(stream, 'function', _token.start, _args.end).add(_token).add(_args);
}
}
return _token || unknown(stream);
}
function any(stream) {
return formatting(stream) || url(stream) || selector(stream) || value(stream)
|| separator(stream);
}
function selector(stream) {
return interpolation(stream) || backtick(stream) || ident(stream) || atKeyword(stream)
|| className(stream) || id(stream) || pseudo(stream) || eatAttribuite(stream)
|| combinator(stream);
}
function value(stream) {
return url(stream) || string(stream) || interpolation(stream) || backtick(stream)
|| number(stream) || hash(stream) || keyword(stream) || important(stream)
|| operator$1(stream);
}
function keyword(stream) {
return backtick(stream) || variable(stream) || atKeyword(stream) || ident(stream);
}
function formatting(stream) {
return comment(stream) || whitespace(stream);
}
function unknown(stream) {
stream.start = stream.pos;
const ch = stream.next();
if (ch != null) {
return new Token(stream, 'unknown');
}
}
/**
* Parses CSS rule selector
* @param {String|StreamReader} source
* @return {Token[]}
*/
function parseSelector(source) {
return parseList(source, 'selector');
}
/**
* Parses CSS property name. Mostly used for LESS where
* property-like entry might be used as a mixin call
* @param {String|StreamReader} source
* @return {Token}
*/
function parsePropertyName(source) {
const stream = typeof source === 'string' ? new _emmetio_stream_reader__WEBPACK_IMPORTED_MODULE_0__["default"](source) : source;
const items = [];
while (!stream.eof()) {
items.push(consumeToken(stream));
}
let token;
if (items.length === 1) {
token = items[0];
} else {
token = new Token(stream, 'property-name', stream.start, stream.end);
for (let i = 0, il = items.length; i < il; i++) {
token.add(items[i]);
}
}
return token;
}
/**
* Parses CSS property value
* @param {String|StreamReader} source
* @return {Token[]}
*/
function parsePropertyValue(source) {
return parseList(source);
}
/**
* Parses @media CSS rule expression
* @param {String|StreamReader} source
* @return {Token[]}
*/
function parseMediaExpression(source) {
return parseList(source);
}
/**
* Parses given source into a set of tokens, separated by comma. Each token contains
* parsed sub-items as independent tokens and so on. Mostly used to parse
* selectors and property values
* @param {String|StreamReader} source Source to parse
* @param {String} [tokenType] Type of first-level tokens.
* Default is `item`
* @return {Token[]}
*/
function parseList(source, tokenType) {
tokenType = tokenType || 'item';
const stream = typeof source === 'string' ? new _emmetio_stream_reader__WEBPACK_IMPORTED_MODULE_0__["default"](source) : source;
const items = [];
const fragments = [];
const flush = () => {
const clean = trimFormatting(fragments);
if (clean.length) {
const item = new Token(stream, tokenType, clean[0].start, last(clean).end);
for (let i = 0; i < clean.length; i++) {
item.add(clean[i]);
}
items.push(item);
}
fragments.length = 0;
};
let token;
while (!stream.eof()) {
if (stream.eat(44 /* , */)) {
flush();
} else if (token = consumeToken(stream)) {
if (token.type !== 'comment') {
fragments.push(token);
}
} else {
throw stream.error('Unexpected character');
}
}
flush();
return items;
}
/**
* Creates CSS rule from given tokens
* @param {StreamReader} stream
* @param {Token[]} tokens
* @param {Token} [content]
* @return {Rule}
*/
function createRule(stream, tokens, contentStart, contentEnd) {
if (!tokens.length) {
return null;
}
const name = tokens[0];
name.end = last(tokens).end;
return new Rule(stream, name, contentStart, contentEnd);
}
/**
* Represents CSS rule
* @type {Node}
*/
class Rule extends Node {
/**
* @param {StreamReader} stream
* @param {Token} name Rules name token
* @param {Token} contentStart Rules content start token
* @param {Token} [contentEnd] Rules content end token
*/
constructor(stream, name, contentStart, contentEnd) {
super('rule');
this.stream = stream;
this.selectorToken = name;
this.contentStartToken = contentStart;
this.contentEndToken = contentEnd || contentStart;
this._parsedSelector = null;
}
/**
* Returns rule selector
* @return {String}
*/
get selector() {
return valueOf(this.selectorToken);
}
get parsedSelector() {
if (!this._parsedSelector) {
this._parsedSelector = parseSelector(this.selectorToken.limit());
}
return this._parsedSelector;
}
/**
* Returns nodes start position in stream
* @return {*}
*/
get start() {
return this.selectorToken && this.selectorToken.start;
}
/**
* Returns nodes end position in stream
* @return {*}
*/
get end() {
const token = this.contentEndToken || this.contentStartToken || this.nameToken;
return token && token.end;
}
}
/**
* Creates CSS rule from given tokens
* @param {StreamReader} stream
* @param {Token[]} tokens
* @param {Token} [content]
* @return {Rule}
*/
function createAtRule(stream, tokens, contentStart, contentEnd) {
if (!tokens.length) {
return null;
}
let ix = 0, expression;
const name = tokens[ix++];
if (ix < tokens.length) {
expression = tokens[ix++];
expression.type = 'expression';
expression.end = last(tokens).end;
} else {
expression = new Token(stream, 'expression', name.end, name.end);
}
return new AtRule(stream, name, expression, contentStart, contentEnd);
}
class AtRule extends Node {
constructor(stream, name, expression, contentStart, contentEnd) {
super('at-rule');
this.stream = stream;
this.nameToken = name;
this.expressionToken = expression;
this.contentStartToken = contentStart;
this.contentEndToken = contentEnd || contentStart;
this._parsedExpression = null;
}
/**
* Returns at-rule name
* @return {String}
*/
get name() {
return valueOf(this.nameToken && this.nameToken.item(0));
}
get expression() {
return valueOf(this.expressionToken);
}
get parsedExpression() {
if (!this._parsedExpression) {
this._parsedExpression = parseMediaExpression(this.expressionToken.limit());
}
return this._parsedExpression;
}
/**
* Returns nodes start position in stream
* @return {*}
*/
get start() {
return this.nameToken && this.nameToken.start;
}
/**
* Returns nodes end position in stream
* @return {*}
*/
get end() {
const token = this.contentEndToken || this.contentStartToken || this.nameToken;
return token && token.end;
}
}
/**
* Factory method that creates property node from given tokens
* @param {StreamReader} stream
* @param {Token[]} tokens
* @param {Token} terminator
* @return {Property}
*/
function createProperty(stream, tokens, terminator) {
// NB in LESS, fragmented properties without value like `.foo.bar;` must be
// treated like mixin call
if (!tokens.length) {
return null;
}
let separator, value, ix = 0;
const name = tokens[ix++];
if (ix < tokens.length) {
value = tokens[ix++];
value.type = 'value';
value.end = last(tokens).end;
}
if (name && value) {
separator = new Token(stream, 'separator', name.end, value.start);
}
return new Property(
stream,
name,
value,
separator,
terminator
);
}
class Property extends Node {
constructor(stream, name, value, separator, terminator) {
super('property');
this.stream = stream;
this.nameToken = name;
this.valueToken = value;
this._parsedName = null;
this._parsedValue = null;
this.separatorToken = separator;
this.terminatorToken = terminator;
}
/**
* Property name
* @return {String}
*/
get name() {
return valueOf(this.nameToken);
}
/**
* Returns parsed sub-tokens of current property name
* @return {Token[]}
*/
get parsedName() {
if (!this._parsedName) {
this._parsedName = parsePropertyName(this.nameToken.limit());
}
return this._parsedName;
}
/**
* Property value
* @return {String}
*/
get value() {
return valueOf(this.valueToken);
}
/**
* Parsed value parts: a list of tokens, separated by comma. Each token may
* contains parsed sub-tokens and so on
* @return {Token[]}
*/
get parsedValue() {
if (!this._parsedValue) {
this._parsedValue = parsePropertyValue(this.valueToken.limit());
}
return this._parsedValue;
}
get separator() {
return valueOf(this.separatorToken);
}
get terminator() {
return valueOf(this.terminatorToken);
}
get start() {
const token = this.nameToken || this.separatorToken || this.valueToken
|| this.terminatorToken;
return token && token.start;
}
get end() {
const token = this.terminatorToken || this.valueToken
|| this.separatorToken || this.nameToken;
return token && token.end;
}
}
const LBRACE = 40; // (
const RBRACE = 41; // )
const PROP_DELIMITER = 58; // :
const PROP_TERMINATOR = 59; // ;
const RULE_START = 123; // {
const RULE_END = 125; // }
function parseStylesheet(source) {
const stream = typeof source === 'string' ? new _emmetio_stream_reader__WEBPACK_IMPORTED_MODULE_0__["default"](source) : source;
const root = new Stylesheet();
let ctx = root, child, accum, token;
let tokens = [];
const flush = () => {
if (accum) {
tokens.push(accum);
accum = null;
}
};
while (!stream.eof()) {
if (eatWhitespace(stream)) {
continue;
}
if (token = comment(stream)) {
root.addComment(token);
continue;
}
stream.start = stream.pos;
if (stream.eatWhile(PROP_DELIMITER)) {
// Property delimiter can be either a real property delimiter or a
// part of pseudo-selector.
if (!tokens.length) {
if (accum) {
// No consumed tokens yet but pending token: most likely its
// a CSS property
flush();
} else {
// No consumend or accumulated token, seems like a start of
// pseudo-selector, e.g. `::slotted`
accum = new Token(stream, 'preparse');
}
}
// Skip delimiter if there are already consumend tokens: most likely
// its a part of pseudo-selector
} else if (stream.eat(PROP_TERMINATOR)) {
flush();
ctx.add(createProperty(stream, tokens, new Token(stream, 'termintator')));
tokens.length = 0;
} else if (stream.eat(RULE_START)) {
flush();
if (tokens.length > 0) {
child = tokens[0].type === 'at-keyword'
? createAtRule(stream, tokens, new Token(stream, 'body-start'))
: createRule(stream, tokens, new Token(stream, 'body-start'));
ctx.add(child);
ctx = child;
tokens.length = 0;
}
} else if (stream.eat(RULE_END)) {
flush();
// Finalize context section
ctx.add(createProperty(stream, tokens));
if (ctx.type !== 'stylesheet') {
// In case of invalid stylesheet with redundant `}`,
// dont modify root section.
ctx.contentEndToken = new Token(stream, 'body-end');
ctx = ctx.parent;
}
tokens.length = 0;
} else if (token = atKeyword(stream)) {
// Explictly consume @-tokens since it defines how rule or property
// should be pre-parsed
flush();
tokens.push(token);
} else if (eatUrl(stream) || eatInterpolation(stream) || eatBacktick(stream)
|| eatBraces(stream, root) || eatString$1(stream) || stream.next()) {
// NB explicitly consume `url()` token since it may contain
// an unquoted url like `http://example.com` which interferes
// with single-line comment
accum = accum || new Token(stream, 'preparse');
accum.end = stream.pos;
} else {
throw new Error(`Unexpected end-of-stream at ${stream.pos}`);
}
}
if (accum) {
tokens.push(accum);
}
// Finalize all the rest properties
ctx.add(createProperty(stream, tokens));
// Finalize unterminated rules
stream.start = stream.pos;
while (ctx && ctx !== root) {
ctx.contentEndToken = new Token(stream, 'body-end');
ctx = ctx.parent;
}
return root;
}
/**
* Parses given source into tokens
* @param {String|StreamReader} source
* @param {Function} [consumer] Token consumer function, for example, `selector`,
* `value` etc. from `lib/tokens` module. Default is generic `consumeToken`
* @return {Token[]}
*/
function lexer(source, consumer) {
consumer = consumer || consumeToken;
const stream = typeof source === 'string' ? new _emmetio_stream_reader__WEBPACK_IMPORTED_MODULE_0__["default"](source) : source;
const result = [];
let token;
while (!stream.eof() && (token = consumer(stream))) {
result.push(token);
}
return result;
}
/**
* Consumes content inside round braces. Mostly used to skip `;` token inside
* expressions since in LESS it is also used to separate function arguments
* @param {StringReader} stream
* @param {Stylesheet} root A stylesheet root. Used to accumulate comments
* @return {Boolean}
*/
function eatBraces(stream, root) {
if (stream.eat(LBRACE)) {
let stack = 1, token;
while (!stream.eof()) {
if (stream.eat(RBRACE)) {
stack--;
if (!stack) {
break;
}
} else if (stream.eat(LBRACE)) {
stack++;
} else if (eatUrl(stream) || eatString$1(stream)) {
continue;
} else if (token = comment(stream)) {
root.addComment(token);
continue;
} else {
stream.next();
}
}
return true;
}
return false;
}
/* harmony default export */ __webpack_exports__["default"] = (parseStylesheet);
/***/ }),
/* 37 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
/* Based on @sergeche's work in his emmet plugin */
const vscode_languageserver_protocol_1 = __webpack_require__(3);
function comparePosition(position, other) {
if (position.line > other.line)
return 1;
if (other.line == position.line && position.character > other.character)
return 1;
if (other.line == position.line && position.character == other.character)
return 0;
return -1;
}
exports.comparePosition = comparePosition;
/**
* A stream reader for VSCode's `TextDocument`
* Based on @emmetio/stream-reader and @emmetio/atom-plugin
*/
class DocumentStreamReader {
constructor(document, pos, limit) {
this.document = document;
this.start = this.pos = pos ? pos : vscode_languageserver_protocol_1.Position.create(0, 0);
this._sof = limit ? limit.start : vscode_languageserver_protocol_1.Position.create(0, 0);
this._eof = limit ? limit.end : vscode_languageserver_protocol_1.Position.create(document.lineCount - 1, this._lineLength(this.document.lineCount - 1));
this._eol = `\n`;
}
/**
* Returns true only if the stream is at the start of the file.
*/
sof() {
return comparePosition(this.pos, this._sof) <= 0;
}
/**
* Returns true only if the stream is at the end of the file.
*/
eof() {
return comparePosition(this.pos, this._eof) >= 0;
}
/**
* Creates a new stream instance which is limited to given range for given document
*/
limit(start, end) {
return new DocumentStreamReader(this.document, start, vscode_languageserver_protocol_1.Range.create(start, end));
}
/**
* Returns the next character code in the stream without advancing it.
* Will return NaN at the end of the file.
*/
peek() {
if (this.eof()) {
return NaN;
}
const line = this.getline(this.pos.line);
return this.pos.character < line.length ? line.charCodeAt(this.pos.character) : this._eol.charCodeAt(0);
}
getline(line) {
let content = this.document.getText();
let lines = content.split('\n');
return lines[line] || '';
}
/**
* Returns the next character in the stream and advances it.
* Also returns NaN when no more characters are available.
*/
next() {
if (this.eof()) {
return NaN;
}
const line = this.getline(this.pos.line);
let code;
if (this.pos.character < line.length) {
code = line.charCodeAt(this.pos.character);
this.pos = vscode_languageserver_protocol_1.Position.create(this.pos.line, this.pos.character + 1);
}
else {
code = this._eol.charCodeAt(this.pos.character - line.length);
this.pos = vscode_languageserver_protocol_1.Position.create(this.pos.line + 1, this.pos.character);
}
if (this.eof()) {
// restrict pos to eof, if in case it got moved beyond eof
this.pos = vscode_languageserver_protocol_1.Position.create(this._eof.line, this._eof.character);
}
return code;
}
/**
* Backs up the stream n characters. Backing it up further than the
* start of the current token will cause things to break, so be careful.
*/
backUp(n) {
let row = this.pos.line;
let column = this.pos.character;
column -= (n || 1);
while (row >= 0 && column < 0) {
row--;
column += this._lineLength(row);
}
this.pos = row < 0 || column < 0
? vscode_languageserver_protocol_1.Position.create(0, 0)
: vscode_languageserver_protocol_1.Position.create(row, column);
return this.peek();
}
/**
* Get the string between the start of the current token and the
* current stream position.
*/
current() {
return this.substring(this.start, this.pos);
}
/**
* Returns contents for given range
*/
substring(from, to) {
return this.document.getText(vscode_languageserver_protocol_1.Range.create(from, to));
}
/**
* Creates error object with current stream state
*/
error(message) {
const err = new Error(`${message} at row ${this.pos.line}, column ${this.pos.character}`);
return err;
}
/**
* Returns line length of given row, including line ending
*/
_lineLength(row) {
const line = this.getline(row);
return line.length;
}
/**
* `match` can be a character code or a function that takes a character code
* and returns a boolean. If the next character in the stream 'matches'
* the given argument, it is consumed and returned.
* Otherwise, `false` is returned.
*/
eat(match) {
const ch = this.peek();
const ok = typeof match === 'function' ? match(ch) : ch === match;
if (ok) {
this.next();
}
return ok;
}
/**
* Repeatedly calls <code>eat</code> with the given argument, until it
* fails. Returns <code>true</code> if any characters were eaten.
*/
eatWhile(match) {
const start = this.pos;
while (!this.eof() && this.eat(match)) { }
return comparePosition(this.pos, start) != 0;
}
}
exports.DocumentStreamReader = DocumentStreamReader;
/***/ }),
/* 38 */
/***/ (function(module, exports) {
module.exports = require("vscode-emmet-helper");
/***/ })
/******/ ])));