Skip to content

Commit

Permalink
Fix #1647 (#1648)
Browse files Browse the repository at this point in the history
* fix

* Fix

* fix
  • Loading branch information
cspotcode authored Feb 19, 2022
1 parent abc616e commit 63a2f83
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 96 deletions.
85 changes: 30 additions & 55 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@
"semver": "^7.1.3",
"throat": "^6.0.1",
"typedoc": "^0.22.10",
"typescript": "4.5.2",
"typescript-json-schema": "^0.51.0",
"typescript": "4.5.5",
"typescript-json-schema": "^0.53.0",
"util.promisify": "^1.0.1"
},
"peerDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ export function create(rawOptions: CreateOptions = {}): Service {
const projectLocalResolveHelper =
createProjectLocalResolveHelper(relativeToPath);
const compiler = projectLocalResolveHelper(name || 'typescript', true);
const ts: typeof _ts = attemptRequireWithV8CompileCache(require, compiler);
const ts: TSCommon = attemptRequireWithV8CompileCache(require, compiler);
return { compiler, ts, projectLocalResolveHelper };
}

Expand Down
90 changes: 54 additions & 36 deletions src/resolver-functions.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { resolve } from 'path';
import type * as _ts from 'typescript';
import type { TSCommon, TSInternal } from './ts-compiler-types';
import type { ProjectLocalResolveHelper } from './util';

/**
* @internal
* In a factory because these are shared across both CompilerHost and LanguageService codepaths
*/
export function createResolverFunctions(kwargs: {
ts: typeof _ts;
host: _ts.ModuleResolutionHost;
ts: TSCommon;
host: TSCommon.ModuleResolutionHost;
cwd: string;
getCanonicalFileName: (filename: string) => string;
config: _ts.ParsedCommandLine;
config: TSCommon.ParsedCommandLine;
projectLocalResolveHelper: ProjectLocalResolveHelper;
}) {
const {
Expand Down Expand Up @@ -58,7 +58,9 @@ export function createResolverFunctions(kwargs: {
* If we need to emit JS for a file, force TS to consider it non-external
*/
const fixupResolvedModule = (
resolvedModule: _ts.ResolvedModule | _ts.ResolvedTypeReferenceDirective
resolvedModule:
| TSCommon.ResolvedModule
| TSCommon.ResolvedTypeReferenceDirective
) => {
const { resolvedFileName } = resolvedModule;
if (resolvedFileName === undefined) return;
Expand All @@ -82,35 +84,36 @@ export function createResolverFunctions(kwargs: {
* Older ts versions do not pass `redirectedReference` nor `options`.
* We must pass `redirectedReference` to newer ts versions, but cannot rely on `options`, hence the weird argument name
*/
const resolveModuleNames: _ts.LanguageServiceHost['resolveModuleNames'] = (
moduleNames: string[],
containingFile: string,
reusedNames: string[] | undefined,
redirectedReference: _ts.ResolvedProjectReference | undefined,
optionsOnlyWithNewerTsVersions: _ts.CompilerOptions
): (_ts.ResolvedModule | undefined)[] => {
return moduleNames.map((moduleName) => {
const { resolvedModule } = ts.resolveModuleName(
moduleName,
containingFile,
config.options,
host,
moduleResolutionCache,
redirectedReference
);
if (resolvedModule) {
fixupResolvedModule(resolvedModule);
}
return resolvedModule;
});
};
const resolveModuleNames: TSCommon.LanguageServiceHost['resolveModuleNames'] =
(
moduleNames: string[],
containingFile: string,
reusedNames: string[] | undefined,
redirectedReference: TSCommon.ResolvedProjectReference | undefined,
optionsOnlyWithNewerTsVersions: TSCommon.CompilerOptions
): (TSCommon.ResolvedModule | undefined)[] => {
return moduleNames.map((moduleName) => {
const { resolvedModule } = ts.resolveModuleName(
moduleName,
containingFile,
config.options,
host,
moduleResolutionCache,
redirectedReference
);
if (resolvedModule) {
fixupResolvedModule(resolvedModule);
}
return resolvedModule;
});
};

// language service never calls this, but TS docs recommend that we implement it
const getResolvedModuleWithFailedLookupLocationsFromCache: _ts.LanguageServiceHost['getResolvedModuleWithFailedLookupLocationsFromCache'] =
const getResolvedModuleWithFailedLookupLocationsFromCache: TSCommon.LanguageServiceHost['getResolvedModuleWithFailedLookupLocationsFromCache'] =
(
moduleName,
containingFile
): _ts.ResolvedModuleWithFailedLookupLocations | undefined => {
): TSCommon.ResolvedModuleWithFailedLookupLocations | undefined => {
const ret = ts.resolveModuleNameFromCache(
moduleName,
containingFile,
Expand All @@ -122,22 +125,37 @@ export function createResolverFunctions(kwargs: {
return ret;
};

const resolveTypeReferenceDirectives: _ts.LanguageServiceHost['resolveTypeReferenceDirectives'] =
const resolveTypeReferenceDirectives: TSCommon.LanguageServiceHost['resolveTypeReferenceDirectives'] =
(
typeDirectiveNames: string[],
typeDirectiveNames: string[] | readonly TSCommon.FileReference[],
containingFile: string,
redirectedReference: _ts.ResolvedProjectReference | undefined,
options: _ts.CompilerOptions
): (_ts.ResolvedTypeReferenceDirective | undefined)[] => {
redirectedReference: TSCommon.ResolvedProjectReference | undefined,
options: TSCommon.CompilerOptions,
containingFileMode?: TSCommon.SourceFile['impliedNodeFormat'] | undefined // new impliedNodeFormat is accepted by compilerHost
): (TSCommon.ResolvedTypeReferenceDirective | undefined)[] => {
// Note: seems to be called with empty typeDirectiveNames array for all files.
// TODO consider using `ts.loadWithTypeDirectiveCache`
return typeDirectiveNames.map((typeDirectiveName) => {
// Copy-pasted from TS source:
const nameIsString = typeof typeDirectiveName === 'string';
const mode = nameIsString
? undefined
: (ts as any as TSInternal).getModeForFileReference!(
typeDirectiveName,
containingFileMode
);
const strName = nameIsString
? typeDirectiveName
: typeDirectiveName.fileName.toLowerCase();
let { resolvedTypeReferenceDirective } =
ts.resolveTypeReferenceDirective(
typeDirectiveName,
strName,
containingFile,
config.options,
host,
redirectedReference
redirectedReference,
undefined,
mode
);
if (typeDirectiveName === 'node' && !resolvedTypeReferenceDirective) {
// Resolve @types/node relative to project first, then __dirname (copy logic from elsewhere / refactor into reusable function)
Expand Down
Loading

0 comments on commit 63a2f83

Please sign in to comment.