Skip to content

Commit

Permalink
tests for module name/ref resolvers
Browse files Browse the repository at this point in the history
  • Loading branch information
isaacs committed Nov 10, 2023
1 parent cd1254e commit f8ec375
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 18 deletions.
15 changes: 11 additions & 4 deletions src/service/resolve-module-name-literals.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import ts from 'typescript'
import { equivalents } from '../equivalents.js'
import { getCurrentDirectory } from '../ts-sys-cached.js'
import { addRootFile } from './file-versions.js'
import { getCanonicalFileName } from './get-canonical-filename.js'
import { getCurrentDirectory } from '../ts-sys-cached.js'
import { tsconfig } from './tsconfig.js'

// reset cache on config change
Expand Down Expand Up @@ -46,10 +46,12 @@ const fixupResolvedModule = (
| ts.ResolvedTypeReferenceDirective
) => {
const { resolvedFileName } = resolvedModule
/* c8 ignore next */
if (resolvedFileName === undefined) return
// [MUST_UPDATE_FOR_NEW_FILE_EXTENSIONS]
// .ts,.mts,.cts is always switched to internal
// .js is switched on-demand
/* c8 ignore start */
if (
resolvedModule.isExternalLibraryImport &&
((resolvedFileName.endsWith('.ts') &&
Expand All @@ -63,6 +65,7 @@ const fixupResolvedModule = (
) {
resolvedModule.isExternalLibraryImport = false
}
/* c8 ignore stop */
if (!resolvedModule.isExternalLibraryImport) {
knownInternalFilenames.add(resolvedFileName)
}
Expand All @@ -89,7 +92,6 @@ export const getResolveModuleNameLiterals = (
containingSourceFile,
_reusedNames
) => {
// moduleLiterals[n].text is the equivalent to moduleName string
return moduleLiterals.map((moduleLiteral, i) => {
const moduleName = moduleLiteral.text
const mode = containingSourceFile
Expand All @@ -104,7 +106,9 @@ export const getResolveModuleNameLiterals = (
| undefined
}
).getModeForResolutionAtIndex?.(containingSourceFile, i)
: undefined
: /* c8 ignore start */
undefined
/* c8 ignore stop */
let { resolvedModule } = ts.resolveModuleName(
moduleName,
containingFile,
Expand All @@ -119,7 +123,10 @@ export const getResolveModuleNameLiterals = (
const ext =
lastDotIndex >= 0 ? moduleName.slice(lastDotIndex) : ''
if (ext) {
const replacements = equivalents(moduleName)
const replacements = equivalents(
moduleName,
mode !== ts.ModuleKind.ESNext
)
for (const rep of replacements) {
;({ resolvedModule } = ts.resolveModuleName(
rep,
Expand Down
19 changes: 11 additions & 8 deletions src/service/resolve-type-reference-directive-references.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import { getCanonicalFileName } from './get-canonical-filename.js'
import { getCurrentDirectory } from '../ts-sys-cached.js'
import { tsconfig } from './tsconfig.js'

const config = tsconfig()

const resolveTypeReferenceDirectiveReferencesInternalCache = new Map<
// ResolveTypeReferenceDirectiveReferences internal cache
const rtrdrInternalCache = new Map<
string,
ts.ResolvedTypeReferenceDirectiveWithFailedLookupLocations
>()
Expand All @@ -15,19 +14,22 @@ export const getResolveTypeReferenceDirectiveReferences = (
host: ts.LanguageServiceHost,
moduleResolutionCache: ts.ModuleResolutionCache
) => {
const config = tsconfig()
const typeReferenceDirectiveResolutionCache =
ts.createTypeReferenceDirectiveResolutionCache(
getCurrentDirectory(),
getCanonicalFileName,
config.options,
moduleResolutionCache.getPackageJsonInfoCache()
)

const resolveTypeReferenceDirectiveReferences = (
typeDirectiveReferences: readonly (ts.FileReference | string)[],
containingFile: string,
redirectedReference: ts.ResolvedProjectReference | undefined,
options: ts.CompilerOptions,
containingSourceFile: ts.SourceFile | string | undefined
containingSourceFile: ts.SourceFile | string | undefined,
_reusedNames?: (ts.FileReference | string)[]
): readonly ts.ResolvedTypeReferenceDirectiveWithFailedLookupLocations[] => {
const entries = typeDirectiveReferences
const resolutionCache = typeReferenceDirectiveResolutionCache
Expand All @@ -40,11 +42,11 @@ export const getResolveTypeReferenceDirectiveReferences = (
resolutionCache: ts.TypeReferenceDirectiveResolutionCache
) => any

/* c8 ignore start */
if (typeDirectiveReferences.length === 0) return []
/* c8 ignore stop */
const resolutions: any[] = []

const cache = resolveTypeReferenceDirectiveReferencesInternalCache

const loader = createLoader(
containingFile,
redirectedReference,
Expand All @@ -59,13 +61,14 @@ export const getResolveTypeReferenceDirectiveReferences = (
containingSourceFile
)
const key = createModeAwareCacheKey(name, mode)
let result = cache.get(key)
let result = rtrdrInternalCache.get(key)
if (!result) {
cache.set(key, (result = loader.resolve(name, mode)))
rtrdrInternalCache.set(key, (result = loader.resolve(name, mode)))
}
resolutions.push(result)
}
return resolutions
}

return resolveTypeReferenceDirectiveReferences
}
107 changes: 107 additions & 0 deletions test/service/resolve-module-name-literals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { resolve } from 'path'
import t from 'tap'
// import { fileURLToPath } from 'url'
// import { getLanguageService } from '../../src/service/language-service.js'
// import { markFileNameInternal } from '../../src/service/resolve-module-name-literals.js'
//
// const svc = getLanguageService()
// svc.getProgram()
//
// markFileNameInternal(fileURLToPath(import.meta.url))

t.test('commonjs program', async t => {
const dir = t.testdir({
'tsconfig.json': JSON.stringify({
include: ['index.ts'],
compilerOptions: {
esModuleInterop: true,
forceConsistentCasingInFileNames: true,
module: 'commonjs',
moduleResolution: 'node10',
skipLibCheck: true,
strict: true,
target: 'es2022',
},
}),
'package.json': JSON.stringify({ type: 'commonjs' }),
'index.ts': `
import assert from 'node:assert'
import './def'
import { bar } from './bar'
import { baz } from './baz'
import t from 'tap'
assert.equal(1, 1)
export type Foo = {
foo: string
}
export const foo = (f: Foo) => f.foo
`,
'bar.cts': `
export const bar = 'bar'
`,
'baz.ts': `
export const baz = 'baz'
`,
})
const cwd = process.cwd()
process.chdir(dir)
t.teardown(() => process.chdir(cwd))
const { getLanguageService } = (await t.mockImport(
'../../src/service/language-service.js'
)) as typeof import('../../src/service/language-service.js')
const { markFileNameInternal } = (await t.mockImport(
'../../src/service/resolve-module-name-literals.js'
)) as typeof import('../../src/service/resolve-module-name-literals.js')
const svc = getLanguageService()
svc.getHost().resolveModuleNameLiterals
svc.getProgram()
markFileNameInternal(resolve(dir, 'index.ts'))
})

t.test('esm program', async t => {
const dir = t.testdir({
'tsconfig.json': JSON.stringify({
include: ['index.ts'],
compilerOptions: {
esModuleInterop: true,
forceConsistentCasingInFileNames: true,
module: 'nodenext',
moduleResolution: 'nodenext',
skipLibCheck: true,
strict: true,
target: 'es2022',
},
}),
'package.json': JSON.stringify({ type: 'module' }),
'index.ts': `
import assert from 'node:assert'
import { bar } from './bar.cjs'
import { baz } from './baz.js'
import t from 'tap'
assert.equal(1, 1)
export type Foo = {
foo: string
}
export const foo = (f: Foo) => f.foo
`,
'bar.cts': `
export const bar = 'bar'
`,
'baz.ts': `
export const baz = 'baz'
`,
})
const cwd = process.cwd()
process.chdir(dir)
t.teardown(() => process.chdir(cwd))
const { getLanguageService } = (await t.mockImport(
'../../src/service/language-service.js'
)) as typeof import('../../src/service/language-service.js')
const { markFileNameInternal } = (await t.mockImport(
'../../src/service/resolve-module-name-literals.js'
)) as typeof import('../../src/service/resolve-module-name-literals.js')
const svc = getLanguageService()
svc.getHost().resolveModuleNameLiterals
svc.getProgram()
markFileNameInternal(resolve(dir, 'index.ts'))
})
5 changes: 5 additions & 0 deletions test/service/resolve-type-reference-directive-references.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import t from 'tap'
import { getLanguageService } from '../../src/service/language-service.js'

getLanguageService().getProgram()
t.pass('just a test file for coverage purposes, nothing to do')
6 changes: 0 additions & 6 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
{
// settings for tsimp importer
"tsimp": {
"compilerOptions": {
"resolveJsonModule": false
}
},
"compilerOptions": {
"declaration": true,
"declarationMap": true,
Expand Down

0 comments on commit f8ec375

Please sign in to comment.