@astrojs/ts-plugin 1.0.9 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/astro-snapshots.js +234 -0
  2. package/dist/astro-sys.js +30 -0
  3. package/dist/astro2tsx.js +26 -0
  4. package/dist/index.js +50 -0
  5. package/dist/language-service/completions.js +45 -0
  6. package/dist/language-service/definition.js +38 -0
  7. package/dist/language-service/diagnostics.js +62 -0
  8. package/dist/language-service/file-references.js +30 -0
  9. package/dist/language-service/find-references.js +66 -0
  10. package/dist/language-service/implementation.js +30 -0
  11. package/dist/language-service/index.js +44 -0
  12. package/dist/language-service/line-column-offset.js +21 -0
  13. package/dist/language-service/rename.js +34 -0
  14. package/dist/logger.js +40 -0
  15. package/dist/module-loader.js +146 -0
  16. package/dist/project-astro-files.js +102 -0
  17. package/dist/utils.js +61 -0
  18. package/package.json +5 -1
  19. package/.turbo/turbo-build.log +0 -4
  20. package/CHANGELOG.md +0 -113
  21. package/src/astro-snapshots.ts +0 -285
  22. package/src/astro-sys.ts +0 -35
  23. package/src/astro2tsx.ts +0 -26
  24. package/src/index.ts +0 -84
  25. package/src/language-service/completions.ts +0 -73
  26. package/src/language-service/definition.ts +0 -42
  27. package/src/language-service/diagnostics.ts +0 -73
  28. package/src/language-service/file-references.ts +0 -34
  29. package/src/language-service/find-references.ts +0 -90
  30. package/src/language-service/implementation.ts +0 -34
  31. package/src/language-service/index.ts +0 -56
  32. package/src/language-service/line-column-offset.ts +0 -24
  33. package/src/language-service/rename.ts +0 -46
  34. package/src/logger.ts +0 -41
  35. package/src/module-loader.ts +0 -219
  36. package/src/project-astro-files.ts +0 -138
  37. package/src/utils.ts +0 -77
  38. package/test/fixtures/MyAstroComponent.astro +0 -5
  39. package/test/fixtures/script.ts +0 -9
  40. package/test/fixtures/tsconfig.json +0 -3
  41. package/test/runTest.js +0 -43
  42. package/test/suite/extension.test.js +0 -78
  43. package/test/suite/index.js +0 -38
  44. package/test/tsconfig.json +0 -14
  45. package/test/utils.js +0 -69
  46. package/tsconfig.json +0 -13
@@ -1,90 +0,0 @@
1
- import type ts from 'typescript/lib/tsserverlibrary';
2
- import type { AstroSnapshotManager } from '../astro-snapshots.js';
3
- import type { Logger } from '../logger';
4
- import { isAstroFilePath, isNotNullOrUndefined } from '../utils.js';
5
-
6
- export function decorateFindReferences(
7
- ls: ts.LanguageService,
8
- snapshotManager: AstroSnapshotManager,
9
- logger: Logger
10
- ): void {
11
- decorateGetReferencesAtPosition(ls, snapshotManager, logger);
12
- _decorateFindReferences(ls, snapshotManager, logger);
13
- }
14
-
15
- function _decorateFindReferences(
16
- ls: ts.LanguageService,
17
- snapshotManager: AstroSnapshotManager,
18
- logger: Logger
19
- ) {
20
- const findReferences = ls.findReferences;
21
- ls.findReferences = (fileName, position) => {
22
- const references = findReferences(fileName, position);
23
- return references
24
- ?.map((reference) => {
25
- const snapshot = snapshotManager.get(reference.definition.fileName);
26
- if (!isAstroFilePath(reference.definition.fileName) || !snapshot) {
27
- return reference;
28
- }
29
-
30
- const textSpan = snapshot.getOriginalTextSpan(reference.definition.textSpan);
31
- if (!textSpan) {
32
- return null;
33
- }
34
-
35
- return {
36
- definition: {
37
- ...reference.definition,
38
- textSpan,
39
- // Spare the work for now
40
- originalTextSpan: undefined,
41
- },
42
- references: mapReferences(reference.references, snapshotManager, logger),
43
- };
44
- })
45
- .filter(isNotNullOrUndefined);
46
- };
47
- }
48
-
49
- function decorateGetReferencesAtPosition(
50
- ls: ts.LanguageService,
51
- snapshotManager: AstroSnapshotManager,
52
- logger: Logger
53
- ) {
54
- const getReferencesAtPosition = ls.getReferencesAtPosition;
55
- ls.getReferencesAtPosition = (fileName, position) => {
56
- const references = getReferencesAtPosition(fileName, position);
57
- return references && mapReferences(references, snapshotManager, logger);
58
- };
59
- }
60
-
61
- function mapReferences(
62
- references: ts.ReferenceEntry[],
63
- snapshotManager: AstroSnapshotManager,
64
- logger: Logger
65
- ): ts.ReferenceEntry[] {
66
- return references
67
- .map((reference) => {
68
- const snapshot = snapshotManager.get(reference.fileName);
69
- if (!isAstroFilePath(reference.fileName) || !snapshot) {
70
- return reference;
71
- }
72
-
73
- const textSpan = snapshot.getOriginalTextSpan(reference.textSpan);
74
- if (!textSpan) {
75
- return null;
76
- }
77
-
78
- logger.debug('Find references; map textSpan: changed', reference.textSpan, 'to', textSpan);
79
-
80
- return {
81
- ...reference,
82
- textSpan,
83
- // Spare the work for now
84
- contextSpan: undefined,
85
- originalTextSpan: undefined,
86
- originalContextSpan: undefined,
87
- };
88
- })
89
- .filter(isNotNullOrUndefined);
90
- }
@@ -1,34 +0,0 @@
1
- import type ts from 'typescript/lib/tsserverlibrary';
2
- import type { AstroSnapshotManager } from '../astro-snapshots.js';
3
- import { isAstroFilePath, isNotNullOrUndefined } from '../utils.js';
4
-
5
- export function decorateGetImplementation(
6
- ls: ts.LanguageService,
7
- snapshotManager: AstroSnapshotManager
8
- ): void {
9
- const getImplementationAtPosition = ls.getImplementationAtPosition;
10
- ls.getImplementationAtPosition = (fileName, position) => {
11
- const implementation = getImplementationAtPosition(fileName, position);
12
- return implementation
13
- ?.map((impl) => {
14
- if (!isAstroFilePath(impl.fileName)) {
15
- return impl;
16
- }
17
-
18
- const textSpan = snapshotManager.get(impl.fileName)?.getOriginalTextSpan(impl.textSpan);
19
- if (!textSpan) {
20
- return undefined;
21
- }
22
-
23
- return {
24
- ...impl,
25
- textSpan,
26
- // Spare the work for now
27
- contextSpan: undefined,
28
- originalTextSpan: undefined,
29
- originalContextSpan: undefined,
30
- };
31
- })
32
- .filter(isNotNullOrUndefined);
33
- };
34
- }
@@ -1,56 +0,0 @@
1
- import type ts from 'typescript/lib/tsserverlibrary';
2
- import type { AstroSnapshotManager } from '../astro-snapshots.js';
3
- import type { Logger } from '../logger';
4
- import { decorateCompletions } from './completions.js';
5
- import { decorateGetDefinition } from './definition.js';
6
- import { decorateDiagnostics } from './diagnostics.js';
7
- import { decorateGetFileReferences } from './file-references.js';
8
- import { decorateFindReferences } from './find-references.js';
9
- import { decorateGetImplementation } from './implementation.js';
10
- import { decorateLineColumnOffset } from './line-column-offset.js';
11
- import { decorateRename } from './rename.js';
12
-
13
- const astroPluginPatchSymbol = Symbol('astroPluginPatchSymbol');
14
-
15
- export function isPatched(ls: ts.LanguageService) {
16
- return (ls as any)[astroPluginPatchSymbol] === true;
17
- }
18
-
19
- export function decorateLanguageService(
20
- ls: ts.LanguageService,
21
- snapshotManager: AstroSnapshotManager,
22
- ts: typeof import('typescript/lib/tsserverlibrary'),
23
- logger: Logger
24
- ): ts.LanguageService {
25
- const proxy = new Proxy(ls, createProxyHandler());
26
-
27
- decorateLineColumnOffset(proxy, snapshotManager);
28
- decorateRename(proxy, snapshotManager, logger);
29
- decorateDiagnostics(proxy, ts);
30
- decorateFindReferences(proxy, snapshotManager, logger);
31
- decorateCompletions(proxy, logger);
32
- decorateGetDefinition(proxy, snapshotManager);
33
- decorateGetImplementation(proxy, snapshotManager);
34
- decorateGetFileReferences(proxy, snapshotManager);
35
-
36
- return proxy;
37
- }
38
-
39
- function createProxyHandler(): ProxyHandler<ts.LanguageService> {
40
- const decorated: Partial<ts.LanguageService> = {};
41
-
42
- return {
43
- get(target, p) {
44
- if (p === astroPluginPatchSymbol) {
45
- return true;
46
- }
47
-
48
- return decorated[p as keyof ts.LanguageService] ?? target[p as keyof ts.LanguageService];
49
- },
50
- set(_, p, value) {
51
- decorated[p as keyof ts.LanguageService] = value;
52
-
53
- return true;
54
- },
55
- };
56
- }
@@ -1,24 +0,0 @@
1
- import type ts from 'typescript/lib/tsserverlibrary';
2
- import type { AstroSnapshotManager } from '../astro-snapshots';
3
- import { isAstroFilePath } from '../utils';
4
-
5
- export function decorateLineColumnOffset(
6
- ls: ts.LanguageService,
7
- snapshotManager: AstroSnapshotManager
8
- ) {
9
- if (!ls.toLineColumnOffset) {
10
- return;
11
- }
12
-
13
- // We need to patch this because (according to source, only) getDefinition uses this
14
- const toLineColumnOffset = ls.toLineColumnOffset;
15
- ls.toLineColumnOffset = (fileName, position) => {
16
- if (isAstroFilePath(fileName)) {
17
- const snapshot = snapshotManager.get(fileName);
18
- if (snapshot) {
19
- return snapshot.positionAt(position);
20
- }
21
- }
22
- return toLineColumnOffset(fileName, position);
23
- };
24
- }
@@ -1,46 +0,0 @@
1
- import type ts from 'typescript/lib/tsserverlibrary';
2
- import type { AstroSnapshotManager } from '../astro-snapshots.js';
3
- import type { Logger } from '../logger.js';
4
- import { isAstroFilePath, isNotNullOrUndefined } from '../utils.js';
5
-
6
- export function decorateRename(
7
- ls: ts.LanguageService,
8
- snapshotManager: AstroSnapshotManager,
9
- logger: Logger
10
- ): void {
11
- const findRenameLocations = ls.findRenameLocations;
12
- ls.findRenameLocations = (fileName, position, findInStrings, findInComments, preferences) => {
13
- const renameLocations = findRenameLocations(
14
- fileName,
15
- position,
16
- findInStrings,
17
- findInComments,
18
- preferences as ts.UserPreferences
19
- );
20
- return renameLocations
21
- ?.map((renameLocation) => {
22
- const snapshot = snapshotManager.get(renameLocation.fileName);
23
- if (!isAstroFilePath(renameLocation.fileName) || !snapshot) {
24
- return renameLocation;
25
- }
26
-
27
- // TODO more needed to filter invalid locations, see RenameProvider
28
- const textSpan = snapshot.getOriginalTextSpan(renameLocation.textSpan);
29
- if (!textSpan) {
30
- return null;
31
- }
32
-
33
- const converted = {
34
- ...renameLocation,
35
- textSpan,
36
- };
37
- if (converted.contextSpan) {
38
- // Not important, spare the work
39
- converted.contextSpan = undefined;
40
- }
41
- logger.debug('Converted rename location ', converted);
42
- return converted;
43
- })
44
- .filter(isNotNullOrUndefined);
45
- };
46
- }
package/src/logger.ts DELETED
@@ -1,41 +0,0 @@
1
- import type ts from 'typescript/lib/tsserverlibrary';
2
-
3
- export class Logger {
4
- constructor(
5
- private tsLogService: ts.server.Logger,
6
- suppressNonAstroLogs = false,
7
- private logDebug = false
8
- ) {
9
- if (suppressNonAstroLogs) {
10
- const log = this.tsLogService.info.bind(this.tsLogService);
11
- this.tsLogService.info = (s: string) => {
12
- if (s.startsWith('-Astro Plugin-')) {
13
- log(s);
14
- }
15
- };
16
- }
17
- }
18
-
19
- log(...args: any[]) {
20
- const str = args
21
- .map((arg) => {
22
- if (typeof arg === 'object') {
23
- try {
24
- return JSON.stringify(arg);
25
- } catch (e) {
26
- return '[object that cannot by stringified]';
27
- }
28
- }
29
- return arg;
30
- })
31
- .join(' ');
32
- this.tsLogService.info('-Astro Plugin- ' + str);
33
- }
34
-
35
- debug(...args: any[]) {
36
- if (!this.logDebug) {
37
- return;
38
- }
39
- this.log(...args);
40
- }
41
- }
@@ -1,219 +0,0 @@
1
- import type ts from 'typescript/lib/tsserverlibrary';
2
- import type { AstroSnapshotManager } from './astro-snapshots.js';
3
- import { createAstroSys } from './astro-sys.js';
4
- import type { Logger } from './logger.js';
5
- import { ensureRealAstroFilePath, isVirtualAstroFilePath } from './utils.js';
6
-
7
- /**
8
- * Caches resolved modules.
9
- */
10
- class ModuleResolutionCache {
11
- private cache = new Map<string, ts.ResolvedModuleFull>();
12
-
13
- /**
14
- * Tries to get a cached module.
15
- */
16
- get(moduleName: string, containingFile: string): ts.ResolvedModuleFull | undefined {
17
- return this.cache.get(this.getKey(moduleName, containingFile));
18
- }
19
-
20
- /**
21
- * Caches resolved module, if it is not undefined.
22
- */
23
- set(
24
- moduleName: string,
25
- containingFile: string,
26
- resolvedModule: ts.ResolvedModuleFull | undefined
27
- ) {
28
- if (!resolvedModule) {
29
- return;
30
- }
31
- this.cache.set(this.getKey(moduleName, containingFile), resolvedModule);
32
- }
33
-
34
- /**
35
- * Deletes module from cache. Call this if a file was deleted.
36
- * @param resolvedModuleName full path of the module
37
- */
38
- delete(resolvedModuleName: string): void {
39
- this.cache.forEach((val, key) => {
40
- if (val.resolvedFileName === resolvedModuleName) {
41
- this.cache.delete(key);
42
- }
43
- });
44
- }
45
-
46
- private getKey(moduleName: string, containingFile: string) {
47
- return containingFile + ':::' + ensureRealAstroFilePath(moduleName);
48
- }
49
- }
50
-
51
- /**
52
- * Creates a module loader than can also resolve `.astro` files.
53
- *
54
- * The typescript language service tries to look up other files that are referenced in the currently open astro file.
55
- * For `.ts`/`.js` files this works, for `.astro` files it does not by default.
56
- * Reason: The typescript language service does not know about the `.astro` file ending,
57
- * so it assumes it's a normal typescript file and searches for files like `../Component.astro.ts`, which is wrong.
58
- * In order to fix this, we need to wrap typescript's module resolution and reroute all `.astro.ts` file lookups to .astro.
59
- */
60
- export function patchModuleLoader(
61
- logger: Logger,
62
- snapshotManager: AstroSnapshotManager,
63
- typescript: typeof ts,
64
- lsHost: ts.LanguageServiceHost,
65
- project: ts.server.Project
66
- ): void {
67
- const astroSys = createAstroSys(logger, typescript);
68
- const moduleCache = new ModuleResolutionCache();
69
- const origResolveModuleNames = lsHost.resolveModuleNames?.bind(lsHost);
70
- const origResolveModuleNamLiterals = lsHost.resolveModuleNameLiterals?.bind(lsHost);
71
-
72
- if (lsHost.resolveModuleNameLiterals) {
73
- lsHost.resolveModuleNameLiterals = resolveModuleNameLiterals;
74
- } else {
75
- lsHost.resolveModuleNames = resolveModuleNames;
76
- }
77
-
78
- const origRemoveFile = project.removeFile.bind(project);
79
- project.removeFile = (info, fileExists, detachFromProject) => {
80
- logger.log('File is being removed. Delete from cache: ', info.fileName);
81
- moduleCache.delete(info.fileName);
82
- return origRemoveFile(info, fileExists, detachFromProject);
83
- };
84
-
85
- // Patch readDirectory so we get completions for .astro files
86
- const origReadDirectory = project.readDirectory.bind(project);
87
- project.readDirectory = (path, extensions, exclude, include, depth) => {
88
- const extensionsWithAstro = (extensions ?? []).concat('.astro', '.md', '.mdx');
89
- return origReadDirectory(path, extensionsWithAstro, exclude, include, depth);
90
- };
91
-
92
- function resolveModuleNames(
93
- moduleNames: string[],
94
- containingFile: string,
95
- reusedNames: string[] | undefined,
96
- redirectedReference: ts.ResolvedProjectReference | undefined,
97
- compilerOptions: ts.CompilerOptions
98
- ): Array<ts.ResolvedModule | undefined> {
99
- // logger.log('Resolving modules names for ' + containingFile);
100
-
101
- // Try resolving all module names with the original method first.
102
- // The ones that are undefined will be re-checked if they are a
103
- // astro file and if so, are resolved, too. This way we can defer
104
- // all module resolving logic except for astro files to TypeScript.
105
- const resolved =
106
- origResolveModuleNames?.(
107
- moduleNames,
108
- containingFile,
109
- reusedNames,
110
- redirectedReference,
111
- compilerOptions
112
- ) || Array.from<undefined>(Array(moduleNames.length));
113
-
114
- return resolved.map((moduleName, idx) => {
115
- const fileName = moduleNames[idx];
116
- if (moduleName || !ensureRealAstroFilePath(fileName).endsWith('.astro')) {
117
- return moduleName;
118
- }
119
-
120
- const cachedModule = moduleCache.get(fileName, containingFile);
121
- if (cachedModule) {
122
- return cachedModule;
123
- }
124
-
125
- const resolvedModule = resolveModuleName(fileName, containingFile, compilerOptions);
126
- moduleCache.set(fileName, containingFile, resolvedModule);
127
- return resolvedModule;
128
- });
129
- }
130
-
131
- function resolveModuleName(
132
- name: string,
133
- containingFile: string,
134
- compilerOptions: ts.CompilerOptions
135
- ): ts.ResolvedModuleFull | undefined {
136
- const astroResolvedModule = typescript.resolveModuleName(
137
- name,
138
- containingFile,
139
- compilerOptions,
140
- astroSys
141
- ).resolvedModule;
142
- if (!astroResolvedModule || !isVirtualAstroFilePath(astroResolvedModule.resolvedFileName)) {
143
- return astroResolvedModule;
144
- }
145
-
146
- const resolvedFileName = ensureRealAstroFilePath(astroResolvedModule.resolvedFileName);
147
- logger.log('Resolved', name, 'to astro file', resolvedFileName);
148
- const snapshot = snapshotManager.create(resolvedFileName);
149
- if (!snapshot) {
150
- return undefined;
151
- }
152
-
153
- const resolvedAstroModule: ts.ResolvedModuleFull = {
154
- extension: typescript.Extension.Tsx,
155
- resolvedFileName,
156
- };
157
- return resolvedAstroModule;
158
- }
159
-
160
- function resolveModuleNameLiterals(
161
- moduleLiterals: readonly ts.StringLiteralLike[],
162
- containingFile: string,
163
- redirectedReference: ts.ResolvedProjectReference | undefined,
164
- options: ts.CompilerOptions,
165
- containingSourceFile: ts.SourceFile,
166
- reusedNames: readonly ts.StringLiteralLike[] | undefined
167
- ): readonly ts.ResolvedModuleWithFailedLookupLocations[] {
168
- logger.log('Resolving modules names for ' + containingFile);
169
- // Try resolving all module names with the original method first.
170
- // The ones that are undefined will be re-checked if they are a
171
- // Astro file and if so, are resolved, too. This way we can defer
172
- // all module resolving logic except for Astro files to TypeScript.
173
- const resolved =
174
- origResolveModuleNamLiterals?.(
175
- moduleLiterals,
176
- containingFile,
177
- redirectedReference,
178
- options,
179
- containingSourceFile,
180
- reusedNames
181
- ) ??
182
- moduleLiterals.map(
183
- (): ts.ResolvedModuleWithFailedLookupLocations => ({
184
- resolvedModule: undefined,
185
- })
186
- );
187
-
188
- return resolved.map((tsResolvedModule, idx) => {
189
- const moduleName = moduleLiterals[idx].text;
190
- if (
191
- tsResolvedModule.resolvedModule ||
192
- !ensureRealAstroFilePath(moduleName).endsWith('.astro')
193
- ) {
194
- return tsResolvedModule;
195
- }
196
-
197
- return resolveAstroModuleNameFromCache(moduleName, containingFile, options);
198
- });
199
- }
200
-
201
- function resolveAstroModuleNameFromCache(
202
- moduleName: string,
203
- containingFile: string,
204
- options: ts.CompilerOptions
205
- ) {
206
- const cachedModule = moduleCache.get(moduleName, containingFile);
207
- if (cachedModule) {
208
- return {
209
- resolvedModule: cachedModule,
210
- };
211
- }
212
-
213
- const resolvedModule = resolveModuleName(moduleName, containingFile, options);
214
- moduleCache.set(moduleName, containingFile, resolvedModule);
215
- return {
216
- resolvedModule: resolvedModule,
217
- };
218
- }
219
- }
@@ -1,138 +0,0 @@
1
- import type ts from 'typescript/lib/tsserverlibrary';
2
- import type { AstroSnapshotManager } from './astro-snapshots';
3
- import { getConfigPathForProject, isAstroFilePath, readProjectAstroFilesFromFs } from './utils';
4
-
5
- export class ProjectAstroFilesManager {
6
- private files = new Set<string>();
7
- private directoryWatchers = new Set<ts.FileWatcher>();
8
-
9
- private static instances = new Map<string, ProjectAstroFilesManager>();
10
-
11
- static getInstance(projectName: string) {
12
- return this.instances.get(projectName);
13
- }
14
-
15
- constructor(
16
- private readonly typescript: typeof ts,
17
- private readonly project: ts.server.Project,
18
- private readonly serverHost: ts.server.ServerHost,
19
- private readonly snapshotManager: AstroSnapshotManager,
20
- private parsedCommandLine: ts.ParsedCommandLine
21
- ) {
22
- this.setupWatchers();
23
- this.updateProjectAstroFiles();
24
-
25
- ProjectAstroFilesManager.instances.set(project.getProjectName(), this);
26
- }
27
-
28
- updateProjectConfig(serviceHost: ts.LanguageServiceHost) {
29
- const parsedCommandLine = serviceHost.getParsedCommandLine?.(
30
- getConfigPathForProject(this.project)
31
- );
32
-
33
- if (!parsedCommandLine) {
34
- return;
35
- }
36
-
37
- this.disposeWatchersAndFiles();
38
- this.parsedCommandLine = parsedCommandLine;
39
- this.setupWatchers();
40
- this.updateProjectAstroFiles();
41
- }
42
-
43
- getFiles() {
44
- return Array.from(this.files);
45
- }
46
-
47
- /**
48
- * Create directory watcher for include and exclude
49
- * The watcher in tsserver doesn't support astro file
50
- * It won't add new created astro file to root
51
- */
52
- private setupWatchers() {
53
- for (const directory in this.parsedCommandLine.wildcardDirectories) {
54
- if (
55
- !Object.prototype.hasOwnProperty.call(this.parsedCommandLine.wildcardDirectories, directory)
56
- ) {
57
- continue;
58
- }
59
-
60
- const watchDirectoryFlags = this.parsedCommandLine.wildcardDirectories[directory];
61
- const watcher = this.serverHost.watchDirectory(
62
- directory,
63
- this.watcherCallback.bind(this),
64
- watchDirectoryFlags === this.typescript.WatchDirectoryFlags.Recursive,
65
- this.parsedCommandLine.watchOptions
66
- );
67
-
68
- this.directoryWatchers.add(watcher);
69
- }
70
- }
71
-
72
- private watcherCallback(fileName: string) {
73
- if (!isAstroFilePath(fileName)) {
74
- return;
75
- }
76
-
77
- // We can't just add the file to the project directly, because
78
- // - the casing of fileName is different
79
- // - we don't know whether the file was added or deleted
80
- this.updateProjectAstroFiles();
81
- }
82
-
83
- private updateProjectAstroFiles() {
84
- const fileNamesAfter = readProjectAstroFilesFromFs(
85
- this.typescript,
86
- this.project,
87
- this.parsedCommandLine
88
- );
89
- const removedFiles = new Set(...this.files);
90
- const newFiles = fileNamesAfter.filter((fileName) => {
91
- const has = this.files.has(fileName);
92
- if (has) {
93
- removedFiles.delete(fileName);
94
- }
95
- return !has;
96
- });
97
-
98
- for (const newFile of newFiles) {
99
- this.addFileToProject(newFile);
100
- this.files.add(newFile);
101
- }
102
- for (const removedFile of removedFiles) {
103
- this.removeFileFromProject(removedFile, false);
104
- this.files.delete(removedFile);
105
- }
106
- }
107
-
108
- private addFileToProject(newFile: string) {
109
- this.snapshotManager.create(newFile);
110
- const snapshot = this.project.projectService.getScriptInfo(newFile);
111
-
112
- if (snapshot) {
113
- this.project.addRoot(snapshot);
114
- }
115
- }
116
-
117
- private removeFileFromProject(file: string, exists = true) {
118
- const info = this.project.getScriptInfo(file);
119
-
120
- if (info) {
121
- this.project.removeFile(info, exists, true);
122
- }
123
- }
124
-
125
- private disposeWatchersAndFiles() {
126
- this.directoryWatchers.forEach((watcher) => watcher.close());
127
- this.directoryWatchers.clear();
128
-
129
- this.files.forEach((file) => this.removeFileFromProject(file));
130
- this.files.clear();
131
- }
132
-
133
- dispose() {
134
- this.disposeWatchersAndFiles();
135
-
136
- ProjectAstroFilesManager.instances.delete(this.project.getProjectName());
137
- }
138
- }