typescript#ResolvedModuleFull TypeScript Examples
The following examples show how to use
typescript#ResolvedModuleFull.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: serviceHost.ts From coffeesense with MIT License | 4 votes |
/**
* Manges 4 set of files
*
* - `LANGUAGE_ID` files in workspace
* - `js/ts` files in workspace
* - `LANGUAGE_ID` files in `node_modules`
* - `js/ts` files in `node_modules`
*/
export function getServiceHost(
tsModule: RuntimeLibrary['typescript'],
env: EnvironmentService,
updatedScriptRegionDocuments: LanguageModelCache<TextDocument>
): IServiceHost {
let currentScriptDoc: TextDocument;
let projectVersion = 1;
let versions = new Map<string, number>();
let localScriptRegionDocuments = new Map<string, TextDocument>();
let nodeModuleSnapshots = new Map<string, ts.IScriptSnapshot>();
let projectFileSnapshots = new Map<string, ts.IScriptSnapshot>();
let moduleResolutionCache = new ModuleResolutionCache();
let parsedConfig: ts.ParsedCommandLine;
let scriptFileNameSet: Set<string>;
let coffeescriptSys: ts.System;
let compilerOptions: ts.CompilerOptions;
let jsHost: ts.LanguageServiceHost;
let registry: ts.DocumentRegistry;
let jsLanguageService: ts.LanguageService;
init();
function getCompilerOptions() {
const compilerOptions = {
...getDefaultCompilerOptions(tsModule),
...parsedConfig.options
};
compilerOptions.allowNonTsExtensions = true;
return compilerOptions;
}
function init() {
projectVersion = 1;
versions = new Map<string, number>();
localScriptRegionDocuments = new Map<string, TextDocument>();
nodeModuleSnapshots = new Map<string, ts.IScriptSnapshot>();
projectFileSnapshots = new Map<string, ts.IScriptSnapshot>();
moduleResolutionCache = new ModuleResolutionCache();
parsedConfig = getParsedConfig(tsModule, env.getProjectRoot(), env.getTsConfigPath(), env.get_file_extensions());
const initialProjectFiles = parsedConfig.fileNames;
logger.logDebug(
`Initializing ServiceHost with ${initialProjectFiles.length} files: ${JSON.stringify(initialProjectFiles)}`
);
scriptFileNameSet = new Set(initialProjectFiles);
coffeescriptSys = getCoffeescriptSys(tsModule, scriptFileNameSet, env);
compilerOptions = getCompilerOptions();
jsHost = createLanguageServiceHost(compilerOptions);
registry = tsModule.createDocumentRegistry(true);
jsLanguageService = tsModule.createLanguageService(jsHost, registry);
}
function updateCurrentCoffeescriptTextDocument(doc: TextDocument) {
const fileFsPath = getFileFsPath(doc.uri);
const filePath = getFilePath(doc.uri);
// When file is not in language service, add it
if (!localScriptRegionDocuments.has(fileFsPath)) {
if (env.get_file_extensions().some(ext => fileFsPath.endsWith(`.${ext}`))) {
scriptFileNameSet.add(filePath);
}
}
if (!currentScriptDoc || doc.uri !== currentScriptDoc.uri || doc.version !== currentScriptDoc.version) {
currentScriptDoc = updatedScriptRegionDocuments.refreshAndGet(doc)!;
const localLastDoc = localScriptRegionDocuments.get(fileFsPath);
if (localLastDoc && currentScriptDoc.languageId !== localLastDoc.languageId) {
// if languageId changed, restart the language service; it can't handle file type changes
jsLanguageService.dispose();
jsLanguageService = tsModule.createLanguageService(jsHost);
}
localScriptRegionDocuments.set(fileFsPath, currentScriptDoc);
scriptFileNameSet.add(filePath);
versions.set(fileFsPath, (versions.get(fileFsPath) || 0) + 1);
projectVersion++;
}
return {
service: jsLanguageService,
scriptDoc: currentScriptDoc
};
}
// External Documents: JS/TS, non Coffeescript documents
function updateExternalDocument(fileFsPath: string) {
// reloaded `tsconfig.json`
if (fileFsPath === env.getTsConfigPath()) {
logger.logInfo(`refresh ts language service when ${fileFsPath} changed.`);
init();
return;
}
// respect tsconfig
// use *internal* function
const configFileSpecs = (parsedConfig as any).configFileSpecs;
const isExcludedFile = (tsModule as any).isExcludedFile;
if (
isExcludedFile &&
configFileSpecs &&
isExcludedFile(fileFsPath, configFileSpecs, env.getProjectRoot(), true, env.getProjectRoot())
) {
return;
}
logger.logInfo(`update ${fileFsPath} in ts language service.`);
const ver = versions.get(fileFsPath) || 0;
versions.set(fileFsPath, ver + 1);
projectVersion++;
// Clear cache so we read the js/ts file from file system again
if (projectFileSnapshots.has(fileFsPath)) {
projectFileSnapshots.delete(fileFsPath);
}
}
function getFileNames() {
return Array.from(scriptFileNameSet);
}
function createLanguageServiceHost(options: ts.CompilerOptions): ts.LanguageServiceHost {
return {
getProjectVersion: () => projectVersion.toString(),
getCompilationSettings: () => options,
getScriptFileNames: () => Array.from(scriptFileNameSet),
getScriptVersion(fileName) {
if (fileName.includes('node_modules')) {
return '0';
}
const normalizedFileFsPath = normalizeFileNameToFsPath(fileName);
const version = versions.get(normalizedFileFsPath);
return version ? version.toString() : '0';
},
getScriptKind(fileName) {
if (fileName.includes('node_modules')) {
return (tsModule as any).getScriptKindFromFileName(fileName);
}
if (isCoffeescriptFile(fileName, env)) {
const uri = URI.file(fileName);
const fileFsPath = normalizeFileNameToFsPath(fileName);
let doc = localScriptRegionDocuments.get(fileFsPath);
if (!doc) {
doc = updatedScriptRegionDocuments.refreshAndGet(
TextDocument.create(uri.toString(), LANGUAGE_ID, 0, tsModule.sys.readFile(fileName) || '')
);
localScriptRegionDocuments.set(fileFsPath, doc);
scriptFileNameSet.add(fileName);
}
return getScriptKind(tsModule, doc.languageId);
} else {
// NOTE: Typescript 2.3 should export getScriptKindFromFileName. Then this cast should be removed.
return (tsModule as any).getScriptKindFromFileName(fileName);
}
},
getDirectories: coffeescriptSys.getDirectories,
directoryExists: coffeescriptSys.directoryExists,
fileExists: coffeescriptSys.fileExists,
readFile: coffeescriptSys.readFile,
readDirectory(
path: string,
extensions?: ReadonlyArray<string>,
exclude?: ReadonlyArray<string>,
include?: ReadonlyArray<string>,
depth?: number
): string[] {
const allExtensions = extensions ? extensions.concat(env.get_file_extensions().map(e => `.${e}`)) : extensions;
return coffeescriptSys.readDirectory(path, allExtensions, exclude, include, depth);
},
resolveModuleNames(moduleNames: string[], containingFile: string): (ts.ResolvedModule | undefined)[] {
// in the normal case, delegate to ts.resolveModuleName
// in the relative-imported.LANGUAGE_ID case, manually build a resolved filename
const result: (ts.ResolvedModule | undefined)[] = moduleNames.map(name => {
const cachedResolvedModule = moduleResolutionCache.getCache(name, containingFile);
if (cachedResolvedModule) {
return cachedResolvedModule;
}
let tsResolvedModule: ResolvedModuleFull | undefined
if (!isCoffeescriptFile(name, env)) {
tsResolvedModule = tsModule.resolveModuleName(
name,
containingFile,
options,
tsModule.sys
).resolvedModule;
if (tsResolvedModule) {
moduleResolutionCache.setCache(name, containingFile, tsResolvedModule);
return tsResolvedModule;
}
// Not .coffee and also completely unknown to ts, so it's either an import to a cs file
// without specifying the extension such as `./some-file` or it is invalid.
// https://github.com/vuejs/vetur/issues/213#issuecomment-305018088
for(const file_ext of env.get_file_extensions()) {
tsResolvedModule = tsModule.resolveModuleName(
`${name}.${file_ext}`,
containingFile,
options,
coffeescriptSys
).resolvedModule;
if(tsResolvedModule) {
break
}
}
} else {
tsResolvedModule = tsModule.resolveModuleName(
name,
containingFile,
options,
coffeescriptSys
).resolvedModule;
}
if (!tsResolvedModule) {
return undefined;
}
if (env.get_file_extensions().some(ext => tsResolvedModule!.resolvedFileName.endsWith(`.${ext}.ts`))) {
const resolvedFileName = tsResolvedModule.resolvedFileName.slice(0, -'.ts'.length);
const uri = URI.file(resolvedFileName);
const resolvedFileFsPath = normalizeFileNameToFsPath(resolvedFileName);
let doc = localScriptRegionDocuments.get(resolvedFileFsPath);
// Coffeescript file not created yet
if (!doc) {
doc = updatedScriptRegionDocuments.refreshAndGet(
TextDocument.create(uri.toString(), LANGUAGE_ID, 0, tsModule.sys.readFile(resolvedFileName) || '')
);
localScriptRegionDocuments.set(resolvedFileFsPath, doc);
scriptFileNameSet.add(resolvedFileName);
}
const extension = doc.languageId === 'typescript' ? tsModule.Extension.Ts : tsModule.Extension.Js;
const tsResolvedCoffeescriptModule = { resolvedFileName, extension };
moduleResolutionCache.setCache(name, containingFile, tsResolvedCoffeescriptModule);
return tsResolvedCoffeescriptModule;
} else {
moduleResolutionCache.setCache(name, containingFile, tsResolvedModule);
return tsResolvedModule;
}
});
return result;
},
getScriptSnapshot: (fileName: string) => {
if (fileName.includes('node_modules')) {
if (nodeModuleSnapshots.has(fileName)) {
return nodeModuleSnapshots.get(fileName);
}
const fileText = tsModule.sys.readFile(fileName) || '';
const snapshot: ts.IScriptSnapshot = {
getText: (start, end) => fileText.substring(start, end),
getLength: () => fileText.length,
getChangeRange: () => void 0
};
nodeModuleSnapshots.set(fileName, snapshot);
return snapshot;
}
const fileFsPath = normalizeFileNameToFsPath(fileName);
// js/ts files in workspace
if (!isCoffeescriptFile(fileFsPath, env)) {
if (projectFileSnapshots.has(fileFsPath)) {
return projectFileSnapshots.get(fileFsPath);
}
// Text = content on disk
const fileText = tsModule.sys.readFile(fileFsPath) || '';
const snapshot: ts.IScriptSnapshot = {
getText: (start, end) => fileText.substring(start, end),
getLength: () => fileText.length,
getChangeRange: () => void 0
};
projectFileSnapshots.set(fileFsPath, snapshot);
return snapshot;
}
// LANGUAGE_ID files in workspace
const doc = localScriptRegionDocuments.get(fileFsPath);
let fileText = '';
if (doc) {
// Text = content in "virtual" module cache file
fileText = doc.getText();
} else {
// Note: This is required in addition to the parsing in embeddedSupport because
// this works for .LANGUAGE_ID files that aren't even loaded by VS Code yet.
const rawCoffeescriptFileText = tsModule.sys.readFile(fileFsPath) || '';
fileText = parseCoffeescriptScript(rawCoffeescriptFileText);
}
return {
getText: (start, end) => fileText.substring(start, end),
getLength: () => fileText.length,
getChangeRange: () => void 0
};
},
getCurrentDirectory: () => env.getProjectRoot(),
getDefaultLibFileName: tsModule.getDefaultLibFilePath,
getNewLine: () => NEWLINE,
useCaseSensitiveFileNames: () => true
};
}
return {
updateCurrentCoffeescriptTextDocument,
updateExternalDocument,
getFileNames,
getComplierOptions: () => compilerOptions,
getLanguageService: () => jsLanguageService,
dispose: () => {
jsLanguageService.dispose();
}
};
}