@vidoc/scip-typescript
Version:
SCIP indexer for TypeScript and JavaScript
211 lines (210 loc) • 7.21 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.TypeScriptLanguageServiceHost = void 0;
exports.normalizeSlashes = normalizeSlashes;
const fs = __importStar(require("fs"));
const crypto = __importStar(require("crypto"));
function normalizeSlashes(path) {
return path.replace(/\\/g, '/');
}
class TypeScriptLanguageServiceHost {
constructor(ts, projectDirectory, compilationSettings, fileNames, dirs) {
this.ts = ts;
this.projectDirectory = projectDirectory;
this.compilationSettings = compilationSettings;
this.dirs = dirs;
this.files = {};
this.directories = {};
fileNames.forEach(fileName => {
this.getScriptSnapshot(fileName);
});
}
_getFileHash(text) {
const hash = crypto.createHash('md5');
hash.update(text);
return hash.digest('hex');
}
_addFile(fileName, text) {
if (typeof text !== 'string' || text.length === 0) {
return this._readFile(fileName);
}
const snapshot = this.ts.ScriptSnapshot.fromString(text);
const version = this._getFileHash(text);
this.files[fileName] = { version, snapshot };
return this.files[fileName];
}
_clearFile(fileName) {
delete this.files[fileName];
}
_readFile(fileName) {
try {
const text = fs.readFileSync(fileName, 'utf8');
return text.length > 0
? this._addFile(fileName, text)
: this._clearFile(fileName);
}
catch (e) {
return this._clearFile(fileName);
}
}
_clearDirectory(directoryName) {
delete this.directories[directoryName];
}
_wasFileModified(fileName) {
const hasFile = !!this.files[fileName];
if (hasFile) {
// reload file from fs
this._readFile(fileName);
}
return hasFile;
}
getDefaultLibFileName(options) {
return this.ts.getDefaultLibFileName(options);
}
// SUPER IMPORTANT FUNCTION WTF
updateFromProject() { }
_wasDirectoryModified(directoryName) {
Object.keys(this.files).forEach(_fileName => {
if (_fileName.indexOf(directoryName) === 0) {
// reload file from fs
this._readFile(_fileName);
}
});
Object.keys(this.directories).forEach(_directoryName => {
if (_directoryName.indexOf(directoryName) === 0) {
this._clearDirectory(_directoryName);
}
});
}
_updateCompilationSettings(options) {
this.compilationSettings = options;
}
getCompilationSettings() {
return this.compilationSettings;
}
getNewLine() {
return '\n';
}
// SKIP: getProjectVersion?(): string;
// NOTE: this can only return '.ts', '.tsx' and '.d.ts' files
getScriptFileNames() {
return Object.keys(this.files).filter(file => /\.tsx?$/.test(file));
}
getScriptKind(fileName) {
const ext = fileName.substr(fileName.lastIndexOf('.'));
switch (ext.toLowerCase()) {
case '.js':
return this.ts.ScriptKind.JS;
case '.jsx':
return this.ts.ScriptKind.JSX;
case '.ts':
return this.ts.ScriptKind.TS;
case '.tsx':
return this.ts.ScriptKind.TSX;
default:
return this.ts.ScriptKind.Unknown;
}
}
getScriptVersion(fileName) {
if (this.files[fileName]) {
return this.files[fileName].version;
}
const scriptInfo = this._readFile(fileName);
return scriptInfo ? scriptInfo.version : '';
}
getScriptSnapshot(fileName) {
if (this.files[fileName]) {
return this.files[fileName].snapshot;
}
const scriptInfo = this._readFile(fileName);
return scriptInfo ? scriptInfo.snapshot : undefined;
}
// SKIP: getLocalizedDiagnosticMessages?(): any;
// SKIP: getCancellationToken?(): HostCancellationToken;
getCurrentDirectory() {
return this.projectDirectory;
}
// log(s: string): void {
// _log.info('TypeScriptLanguageServiceHost', s);
// }
useCaseSensitiveFileNames() {
return true;
}
// SKIP: resolveModuleNames?(moduleNames: string[], containingFile: string): ResolvedModule[];
// SKIP: resolveTypeReferenceDirectives?(typeDirectiveNames: string[],
// containingFile: string): ResolvedTypeReferenceDirective[];
directoryExists(directoryName) {
if (this.directories[directoryName]) {
return true;
}
let exists;
try {
exists = fs.statSync(directoryName).isDirectory();
}
catch (e) {
exists = false;
}
if (exists) {
this.directories[directoryName] = this.getDirectories(directoryName);
}
return exists;
}
getDirectories(directoryName) {
return this.dirs;
}
/*
* LS host can optionally implement these methods to support completions for module specifiers.
* Without these methods, only completions for ambient modules will be provided.
*/
/* TODO:
readDirectory(
dirPath: string,
extensions?: ReadonlyArray<string>,
exclude?: ReadonlyArray<string>,
include?: ReadonlyArray<string>,
depth?: number
): string[] {
return fs.readdirSync(dirPath);
}
*/
readFile(filePath, encoding) {
return fs.readFileSync(filePath, { encoding: 'utf8' });
}
fileExists(filePath) {
return fs.existsSync(filePath);
}
}
exports.TypeScriptLanguageServiceHost = TypeScriptLanguageServiceHost;