-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Include type reference directives in symlink cache, wait until program is present to create it #44259
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Include type reference directives in symlink cache, wait until program is present to create it #44259
Changes from all commits
b5df1c5
7c72d49
16e40e2
3794e04
a522672
e066ba4
6cc27a0
e221f9e
287dfe3
db65084
8c439fa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1594,6 +1594,7 @@ namespace ts.Completions { | |
|
||
function tryGetImportCompletionSymbols(): GlobalsSearch { | ||
if (!importCompletionNode) return GlobalsSearch.Continue; | ||
isNewIdentifierLocation = true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I discovered this was missing only because I added fourslash server tests... unrelated to main change |
||
collectAutoImports(/*resolveModuleSpecifiers*/ true); | ||
return GlobalsSearch.Success; | ||
} | ||
|
@@ -1762,7 +1763,7 @@ namespace ts.Completions { | |
// If we don't need to resolve module specifiers, we can use any re-export that is importable at all | ||
// (We need to ensure that at least one is importable to show a completion.) | ||
const { moduleSpecifier, exportInfo } = resolveModuleSpecifiers | ||
? codefix.getModuleSpecifierForBestExportInfo(info, sourceFile, program, host, preferences) | ||
? codefix.getModuleSpecifierForBestExportInfo(info, sourceFile, program, host, preferences) || {} | ||
: { moduleSpecifier: undefined, exportInfo: find(info, isImportableExportInfo) }; | ||
if (!exportInfo) return; | ||
const moduleFile = tryCast(exportInfo.moduleSymbol.valueDeclaration, isSourceFile); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
namespace ts.projectSystem { | ||
const appTsconfigJson: File = { | ||
path: "/packages/app/tsconfig.json", | ||
content: ` | ||
{ | ||
"compilerOptions": { | ||
"module": "commonjs", | ||
"outDir": "dist", | ||
"rootDir": "src", | ||
"baseUrl": "." | ||
} | ||
"references": [{ "path": "../dep" }] | ||
}` | ||
}; | ||
|
||
const appSrcIndexTs: File = { | ||
path: "/packages/app/src/index.ts", | ||
content: `import "dep/does/not/exist";` | ||
}; | ||
|
||
const depPackageJson: File = { | ||
path: "/packages/dep/package.json", | ||
content: `{ "name": "dep", "main": "dist/index.js", "types": "dist/index.d.ts" }` | ||
}; | ||
|
||
const depTsconfigJson: File = { | ||
path: "/packages/dep/tsconfig.json", | ||
content: ` | ||
{ | ||
"compilerOptions": { "outDir": "dist", "rootDir": "src", "module": "commonjs" } | ||
}` | ||
}; | ||
|
||
const depSrcIndexTs: File = { | ||
path: "/packages/dep/src/index.ts", | ||
content: ` | ||
import "./sub/folder";` | ||
}; | ||
|
||
const depSrcSubFolderIndexTs: File = { | ||
path: "/packages/dep/src/sub/folder/index.ts", | ||
content: `export const dep = 0;` | ||
}; | ||
|
||
const link: SymLink = { | ||
path: "/packages/app/node_modules/dep", | ||
symLink: "../../dep", | ||
}; | ||
|
||
describe("unittests:: tsserver:: symlinkCache", () => { | ||
it("contains symlinks discovered by project references resolution after program creation", () => { | ||
const { session, projectService } = setup(); | ||
openFilesForSession([appSrcIndexTs], session); | ||
const project = projectService.configuredProjects.get(appTsconfigJson.path)!; | ||
assert.deepEqual( | ||
project.getSymlinkCache()?.getSymlinkedDirectories()?.get(link.path + "/" as Path), | ||
{ real: "/packages/dep/", realPath: "/packages/dep/" as Path } | ||
Comment on lines
+55
to
+57
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This proves that |
||
); | ||
}); | ||
}); | ||
|
||
function setup() { | ||
const host = createServerHost([ | ||
appTsconfigJson, | ||
appSrcIndexTs, | ||
depPackageJson, | ||
depTsconfigJson, | ||
depSrcIndexTs, | ||
depSrcSubFolderIndexTs, | ||
link, | ||
]); | ||
const session = createSession(host); | ||
const projectService = session.getProjectService(); | ||
return { | ||
host, | ||
projectService, | ||
session, | ||
}; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While refactoring for better preservation of a single SymlinkCache instance, I decided to get rid of this fallback.
ModuleSpecifierResolutionHost
is internal and all our implementations of it implementgetSymlinkCache
. It always delegates toProgram.getSymlinkCache
which delegates toProject.getSymlinkCache
, but Program itself has a fallback. This should never be called directly by public API consumers, and even those who are using internal things should be taken care of viats.createModuleSpecifierResolutionHost
, so I think this is safe to remove.