alm
Version:
The best IDE for TypeScript
173 lines (172 loc) • 8.03 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var lsh = require("../../../languageServiceHost/languageServiceHost");
var languageServiceHost = new lsh.LanguageServiceHost(undefined);
var languageService = ts.createLanguageService(languageServiceHost);
/**
* ts syntax highlighter doesn't handle bom correctly so fix that
*/
var BOM_CHAR_CODE = 65279;
var hasBom = Object.create(null);
function addFile(filePath, contents) {
hasBom[filePath] = contents.charCodeAt(0) === BOM_CHAR_CODE;
languageServiceHost.addScript(filePath, contents);
}
exports.addFile = addFile;
function removeFile(filePath) {
languageServiceHost.removeFile(filePath);
}
exports.removeFile = removeFile;
function editFile(filePath, codeEdit) {
languageServiceHost.applyCodeEdit(filePath, codeEdit.from, codeEdit.to, codeEdit.newText);
}
exports.editFile = editFile;
function setContents(filePath, contents) {
hasBom[filePath] = contents.charCodeAt(0) === BOM_CHAR_CODE;
languageServiceHost.setContents(filePath, contents);
}
exports.setContents = setContents;
function getLineAndCharacterOfPosition(filePath, pos) {
return languageServiceHost.getLineAndCharacterOfPosition(filePath, pos);
}
exports.getLineAndCharacterOfPosition = getLineAndCharacterOfPosition;
function getPositionOfLineAndCharacter(filePath, line, ch) {
return languageServiceHost.getPositionOfLineAndCharacter(filePath, line, ch);
}
exports.getPositionOfLineAndCharacter = getPositionOfLineAndCharacter;
function getSourceFile(filePath) {
return languageService.getNonBoundSourceFile(filePath);
}
exports.getSourceFile = getSourceFile;
function getClassificationsForLine(filePath, lineStart, string) {
var offsetForBom = hasBom[filePath] ? -1 : 0;
// don't need this for monaco!
/**
* Protect against code mirror optimized rendering.
* If string does not match expected line contents tokenize as whitespace till the precise call is made.
*/
// const trueLineContents = languageService.getNonBoundSourceFile(filePath).text.substr(lineStart);
// if (!trueLineContents.startsWith(string)){
// // console.log({ trueLineContents, string, filePath }); // DEBUG
// const cantDoIt = [{
// textSpan: {
// start:0,
// length: string.length
// },
// startInLine: 0,
// string,
// classificationType: ts.ClassificationType.whiteSpace,
// classificationTypeName: ClassificationTypeNames.whiteSpace,
// }];
// return cantDoIt;
// }
var lineLength = string.length;
var encodedClassifications = languageService.getEncodedSyntacticClassifications(filePath, { start: lineStart, length: lineLength });
var classifications = unencodeClassifications(encodedClassifications);
/** for some reason we have dupes on first token sometimes. this helps remove them */
var lastStartSet = false;
var lastStart = 0;
// Trim to the query region
classifications = classifications
.map(function (c, i) {
// Compensate each token for bom
c.textSpan.start += offsetForBom;
// completely outside the range on the left
if ((c.textSpan.start + c.textSpan.length) <= lineStart) {
return null;
}
// completely outside the range on the right
if (c.textSpan.start > (lineStart + lineLength)) {
return null;
}
// trim the left
if (c.textSpan.start < lineStart) {
c.textSpan.length = c.textSpan.start + c.textSpan.length - lineStart;
c.textSpan.start = lineStart;
}
// trim the right
if ((c.textSpan.start + c.textSpan.length) > (lineStart + lineLength)) {
c.textSpan.length = (lineStart + lineLength) - (c.textSpan.start);
}
// dedupe...first token only
if (!lastStartSet) {
lastStartSet = true;
lastStart = c.textSpan.start;
}
else {
if (c.textSpan.start == lastStart) {
return null;
}
}
return c;
})
.filter(function (c) { return !!c; });
// Add a string for easier debugging + startInLine for creating a 'map' of positions later on
classifications.forEach(function (c) {
c.startInLine = c.textSpan.start - lineStart;
c.string = string.substr(c.startInLine, c.textSpan.length);
});
return classifications;
}
exports.getClassificationsForLine = getClassificationsForLine;
function getIndentationAtPosition(filePath, lineStart, options) {
return languageService.getIndentationAtPosition(filePath, lineStart, options);
}
exports.getIndentationAtPosition = getIndentationAtPosition;
function getFormattingEditsAfterKeystroke(filePath, position, key, options) {
return languageService.getFormattingEditsAfterKeystroke(filePath, position, key, options);
}
exports.getFormattingEditsAfterKeystroke = getFormattingEditsAfterKeystroke;
/**
* ported from services.ts convertClassifications
* encoding is [[start,lenght,type]......]
* also added whitespace support
*/
function unencodeClassifications(classifications) {
var dense = classifications.spans;
var result = [];
var expectedStart = 0; // used for whitespace
for (var i = 0, n = dense.length; i < n; i += 3) {
if (dense[i] > expectedStart) {
result.push({
textSpan: ts.createTextSpan(expectedStart, dense[i] - expectedStart),
classificationType: ts.ClassificationType.whiteSpace,
classificationTypeName: ts.ClassificationTypeNames.whiteSpace,
});
}
result.push({
textSpan: ts.createTextSpan(dense[i], dense[i + 1]),
classificationType: dense[i + 2],
classificationTypeName: getClassificationTypeName(dense[i + 2]),
});
expectedStart = dense[i] + dense[i + 1];
}
return result;
}
/** brought in as it is */
var ClassificationType = ts.ClassificationType;
var ClassificationTypeNames = ts.ClassificationTypeNames;
function getClassificationTypeName(type) {
switch (type) {
case ClassificationType.comment: return ClassificationTypeNames.comment;
case ClassificationType.identifier: return ClassificationTypeNames.identifier;
case ClassificationType.keyword: return ClassificationTypeNames.keyword;
case ClassificationType.numericLiteral: return ClassificationTypeNames.numericLiteral;
case ClassificationType.operator: return ClassificationTypeNames.operator;
case ClassificationType.stringLiteral: return ClassificationTypeNames.stringLiteral;
case ClassificationType.whiteSpace: return ClassificationTypeNames.whiteSpace;
case ClassificationType.text: return ClassificationTypeNames.text;
case ClassificationType.punctuation: return ClassificationTypeNames.punctuation;
case ClassificationType.className: return ClassificationTypeNames.className;
case ClassificationType.enumName: return ClassificationTypeNames.enumName;
case ClassificationType.interfaceName: return ClassificationTypeNames.interfaceName;
case ClassificationType.moduleName: return ClassificationTypeNames.moduleName;
case ClassificationType.typeParameterName: return ClassificationTypeNames.typeParameterName;
case ClassificationType.typeAliasName: return ClassificationTypeNames.typeAliasName;
case ClassificationType.parameterName: return ClassificationTypeNames.parameterName;
case ClassificationType.docCommentTagName: return ClassificationTypeNames.docCommentTagName;
case ClassificationType.jsxOpenTagName: return ClassificationTypeNames.jsxOpenTagName;
case ClassificationType.jsxCloseTagName: return ClassificationTypeNames.jsxCloseTagName;
case ClassificationType.jsxSelfClosingTagName: return ClassificationTypeNames.jsxSelfClosingTagName;
}
}