UNPKG

els-addon-typed-templates

Version:
230 lines 10.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.toDiagnostic = exports.getSemanticDiagnostics = exports.getFullSemanticDiagnostics = exports.tsDefinitionToLocation = exports.offsetToRange = exports.normalizeCompletions = exports.normalizeDefinitions = void 0; const vscode_uri_1 = require("vscode-uri"); const vscode_languageserver_1 = require("vscode-languageserver"); const fs = require("fs"); const path = require("path"); const utils_1 = require("./utils"); const ast_helpers_1 = require("./ast-helpers"); function normalizeDefinitions(results, root) { return (results || []) .map(el => { return tsDefinitionToLocation(el, root); }).filter((el) => el !== null); } exports.normalizeDefinitions = normalizeDefinitions; const ignoreNames = ['willDestroy', 'toString']; function normalizeCompletions(tsResults, realPath, isArg) { return (tsResults ? tsResults.entries : []) .filter(({ name }) => !ignoreNames.includes(name) && !name.startsWith("_t") && !name.includes(' - ') && name !== 'globalScope' && name !== 'defaultYield') .map(el => { return { label: isArg ? ast_helpers_1.serializeArgumentName(realPath) + el.name : realPath + el.name, data: el.name, kind: utils_1.itemKind(el.kind) }; }); // .map(el => { // let fixedLabelParts = el.label.split('.'); // fixedLabelParts[fixedLabelParts.length - 1] = el.data; // return { // kind: el.kind, // label: fixedLabelParts.join('.') // } // }); } exports.normalizeCompletions = normalizeCompletions; function offsetToRange(start, limit, source) { let rLines = /(.*?(?:\r\n?|\n|$))/gm; let startLine = source.slice(0, start).match(rLines) || []; if (!source || startLine.length < 2) { return vscode_languageserver_1.Range.create(0, 0, 0, 0); } let line = startLine.length - 2; let col = startLine[startLine.length - 2].length; let endLine = source.slice(start, limit).match(rLines) || []; let endCol = col; let endLineNumber = line; if (endLine.length === 1) { endCol = col + limit; endLineNumber = line + endLine.length - 1; } else { endCol = endLine[endLine.length - 1].length; } return vscode_languageserver_1.Range.create(line, col, endLineNumber, endCol); } exports.offsetToRange = offsetToRange; function tsDefinitionToLocation(el, root) { let scope = el.textSpan; let fullPath = path.resolve(el.fileName); if (!fs.existsSync(fullPath)) { fullPath = path.resolve(path.join(root, el.fileName)); if (!fs.existsSync(fullPath)) { return null; } } let file = fs.readFileSync(fullPath, "utf8"); return vscode_languageserver_1.Location.create(vscode_uri_1.URI.file(fullPath).toString(), offsetToRange(scope.start, scope.length, file)); } exports.tsDefinitionToLocation = tsDefinitionToLocation; function messageConverter(msg) { if (msg.startsWith("The 'this' context of type 'this' is not assignable to method's 'this' of type 'null'.")) { return "Unable to find context, is file created and property defined?"; } console.log(msg); return msg; } function getSeverity(msg) { let severity = vscode_languageserver_1.DiagnosticSeverity.Error; if (msg.startsWith("Object is possibly 'undefined'")) { severity = vscode_languageserver_1.DiagnosticSeverity.Warning; } else if (msg.startsWith("Object is possibly 'null'")) { severity = vscode_languageserver_1.DiagnosticSeverity.Warning; } return severity; } function toFullDiagnostic(err) { if (!err.file || err.start === undefined) { return null; } let preErrorText = err.file.text.slice(0, err.start); let postErrorText = err.file.text.slice(err.start, err.file.text.length); // try { // console.log('err.file.fileName', err.file.fileName); // console.log('start', err.start); // console.log('err.slice', err.file.text.slice(err.start, 100)); // console.log('err.code', err.code); // console.log('err.category', err.category); // console.log('err.related', err.relatedInformation); // console.log('err.source', err.source); // console.log('err.msg', err.messageText); // } catch(e) { // console.log('err:', e); // } if (err.start < err.file.text.indexOf('@mark-meaningful-issues-start')) { return null; } let closestLeftMark = postErrorText.indexOf('["'); let closestRightMarkOffset = postErrorText.indexOf('"]'); let maybeMark = err.file.text.slice(closestLeftMark + err.start, closestRightMarkOffset + err.start); let hasNewline = err.file.text.slice(err.start, err.start + closestLeftMark).split('\n').length > 1; maybeMark = maybeMark.slice(maybeMark.indexOf('[') + 2, maybeMark.indexOf(']')).trim().split(' - ')[0]; let start, end; if (maybeMark.includes(':') && !hasNewline) { [start, end] = maybeMark.split(':'); } else { let preError = preErrorText.slice(preErrorText.lastIndexOf('//@mark'), preErrorText.length); let mark = preError.slice(preError.indexOf('[') + 1, preError.indexOf(']')).trim(); [start, end] = mark.split(':'); } if (!start || !end) { let postError = err.file.text.slice(err.start, err.file.text.length); let postErrorMark = postError.slice(postError.indexOf('/*@path-mark ') + 13, postError.indexOf('*/')); [start, end] = postErrorMark.split(':'); if (!start || !end) { console.log(err); return null; } } // console.log({mark, start, end}) // console.log('preErrorText',preErrorText.slice(preErrorText.lastIndexOf('//@mark ') + 8, preErrorText.lastIndexOf('//@mark ') + 40)); let [startCol, startRow] = start.split(',').map((e) => parseInt(e, 10)); let [endCol, endRow] = end.split(',').map((e) => parseInt(e, 10)); let msgText = diagnosticToString(err.messageText); /* since ember components in addons may be like ... export default Ember.Component.extend(Base, PromiseResolver, { it's really tricky to get typings for it at all, and I prefer to skip warnings for it in next lines */ if (msgText.startsWith("Object is of type 'unknown'")) { return null; } if (msgText.startsWith("Type 'any' is not assignable to type 'never'")) { return null; } if (msgText.startsWith("Property 'args' does not exist on type")) { return null; } if (msgText.startsWith("Expected 0 arguments, but got 2.")) { return null; } if (msgText.startsWith("Cannot invoke an object which is possibly")) { return null; } return { severity: getSeverity(msgText), range: vscode_languageserver_1.Range.create(startCol - 1, startRow, endCol - 1, endRow), message: messageConverter(msgText), source: "typed-templates" }; } // regards to https://github.com/dfreeman/ember-typed-templates-vscode/blob/master/src/server/server.ts#L172 function diagnosticToString(message, indent = '') { if (typeof message === 'string') { return `${indent}${message}`; } else if (message.next && message.next.length) { let items = message.next.map((msg) => diagnosticToString(msg, `${indent} `)); return `${indent}${message.messageText}\n${items.join('\n')}`; } else { return `${indent}${message.messageText}`; } } function getFullSemanticDiagnostics(service, fileName) { const tsDiagnostics = service.getSemanticDiagnostics(fileName); const results = tsDiagnostics.map((error) => toFullDiagnostic(error)).filter((el) => el !== null); const diagnostics = results; return diagnostics; } exports.getFullSemanticDiagnostics = getFullSemanticDiagnostics; function getSemanticDiagnostics(server, service, templateRange, fileName, focusPath, uri) { // console.log(service.getSyntacticDiagnostics(fileName).map((el)=>{ // console.log('getSyntacticDiagnostics', el.messageText, el.start, el.length); // })); // console.log('getSemanticDiagnostics', fileName); const tsDiagnostics = service.getSemanticDiagnostics(fileName); const diagnostics = tsDiagnostics.map((error) => toDiagnostic(error, templateRange, focusPath)); server.connection.sendDiagnostics({ uri, diagnostics }); // console.log(service.getSemanticDiagnostics(fileName).map((el)=>{ // const diagnostics: Diagnostic[] = errors.map((error: any) => toDiagnostic(el)); // server.connection.sendDiagnostics({ uri: textDocument.uri, diagnostics }); // console.log('getSemanticDiagnostics', el.messageText, el.start, el.length); // })); // console.log(service.getSuggestionDiagnostics(fileName).map((el)=>{ // console.log('getSuggestionDiagnostics', el.messageText, el.start, el.length); // })); // console.log('getCompilerOptionsDiagnostics', service.getCompilerOptionsDiagnostics()); } exports.getSemanticDiagnostics = getSemanticDiagnostics; function toDiagnostic(err, [startIndex, endIndex], focusPath) { let errText = err.file.text.slice(err.start, err.start + err.length); if ((err.start >= startIndex && err.length + err.start <= endIndex) || errText.startsWith("return ")) { let loc = focusPath.node.loc; return { severity: getSeverity(err.messageText), range: loc ? vscode_languageserver_1.Range.create(loc.start.line - 1, loc.start.column, loc.end.line - 1, loc.end.column) : vscode_languageserver_1.Range.create(0, 0, 0, 0), message: messageConverter(err.messageText), source: "typed-templates" }; } else { return { severity: getSeverity(err.messageText), range: offsetToRange(0, 0, ""), message: messageConverter(err.messageText), source: "typed-templates" }; } } exports.toDiagnostic = toDiagnostic; //# sourceMappingURL=ls-utils.js.map