@astrojs/ts-plugin 0.2.1 → 0.4.0

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 (54) hide show
  1. package/.turbo/turbo-build.log +5 -2
  2. package/CHANGELOG.md +16 -0
  3. package/LICENSE +36 -0
  4. package/README.md +1 -1
  5. package/dist/astro-snapshots.js +48 -47
  6. package/dist/astro-sys.js +22 -35
  7. package/dist/astro2tsx.js +17 -41
  8. package/dist/index.js +38 -39
  9. package/dist/language-service/completions.js +42 -42
  10. package/dist/language-service/definition.js +22 -40
  11. package/dist/language-service/diagnostics.js +15 -18
  12. package/dist/language-service/file-references.js +52 -0
  13. package/dist/language-service/find-references.js +20 -38
  14. package/dist/language-service/implementation.js +18 -37
  15. package/dist/language-service/index.js +26 -42
  16. package/dist/language-service/line-column-offset.js +44 -0
  17. package/dist/language-service/rename.js +24 -37
  18. package/dist/logger.js +18 -5
  19. package/dist/module-loader.js +28 -22
  20. package/dist/project-astro-files.js +125 -0
  21. package/dist/utils.js +34 -19
  22. package/dist/workers/TSXService.js +39 -0
  23. package/dist/workers/TSXWorker.js +9 -0
  24. package/package.json +36 -27
  25. package/src/astro-snapshots.ts +270 -291
  26. package/src/astro-sys.ts +22 -22
  27. package/src/astro2tsx.ts +5 -50
  28. package/src/index.ts +49 -60
  29. package/src/language-service/completions.ts +56 -64
  30. package/src/language-service/definition.ts +35 -42
  31. package/src/language-service/diagnostics.ts +32 -33
  32. package/src/language-service/file-references.ts +31 -0
  33. package/src/language-service/find-references.ts +67 -76
  34. package/src/language-service/implementation.ts +27 -34
  35. package/src/language-service/index.ts +17 -32
  36. package/src/language-service/line-column-offset.ts +21 -0
  37. package/src/language-service/rename.ts +38 -48
  38. package/src/logger.ts +32 -36
  39. package/src/module-loader.ts +124 -124
  40. package/src/project-astro-files.ts +130 -0
  41. package/src/utils.ts +54 -45
  42. package/src/workers/TSXService.ts +11 -0
  43. package/src/workers/TSXWorker.ts +8 -0
  44. package/test/fixtures/MyAstroComponent.astro +5 -0
  45. package/test/fixtures/script.ts +9 -0
  46. package/test/fixtures/tsconfig.json +3 -0
  47. package/test/runTest.js +41 -0
  48. package/test/suite/extension.test.js +68 -0
  49. package/test/suite/index.js +38 -0
  50. package/test/tsconfig.json +14 -0
  51. package/test/utils.js +65 -0
  52. package/tsconfig.json +2 -1
  53. package/dist/source-mapper.js +0 -114
  54. package/src/source-mapper.ts +0 -123
@@ -1,95 +1,86 @@
1
1
  import type ts from 'typescript/lib/tsserverlibrary';
2
- import { Logger } from '../logger';
3
- import { AstroSnapshotManager } from '../astro-snapshots.js';
4
- import { isNotNullOrUndefined, isAstroFilePath } from '../utils.js';
2
+ import type { AstroSnapshotManager } from '../astro-snapshots.js';
3
+ import type { Logger } from '../logger';
4
+ import { isAstroFilePath, isNotNullOrUndefined } from '../utils.js';
5
5
 
6
6
  export function decorateFindReferences(
7
- ls: ts.LanguageService,
8
- snapshotManager: AstroSnapshotManager,
9
- logger: Logger
7
+ ls: ts.LanguageService,
8
+ snapshotManager: AstroSnapshotManager,
9
+ logger: Logger
10
10
  ): void {
11
- decorateGetReferencesAtPosition(ls, snapshotManager, logger);
12
- _decorateFindReferences(ls, snapshotManager, logger);
11
+ decorateGetReferencesAtPosition(ls, snapshotManager, logger);
12
+ _decorateFindReferences(ls, snapshotManager, logger);
13
13
  }
14
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
- }
15
+ function _decorateFindReferences(ls: ts.LanguageService, snapshotManager: AstroSnapshotManager, logger: Logger) {
16
+ const findReferences = ls.findReferences;
17
+ ls.findReferences = (fileName, position) => {
18
+ const references = findReferences(fileName, position);
19
+ return references
20
+ ?.map((reference) => {
21
+ const snapshot = snapshotManager.get(reference.definition.fileName);
22
+ if (!isAstroFilePath(reference.definition.fileName) || !snapshot) {
23
+ return reference;
24
+ }
29
25
 
30
- const textSpan = snapshot.getOriginalTextSpan(reference.definition.textSpan);
31
- if (!textSpan) {
32
- return null;
33
- }
26
+ const textSpan = snapshot.getOriginalTextSpan(reference.definition.textSpan);
27
+ if (!textSpan) {
28
+ return null;
29
+ }
34
30
 
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
- };
31
+ return {
32
+ definition: {
33
+ ...reference.definition,
34
+ textSpan,
35
+ // Spare the work for now
36
+ originalTextSpan: undefined,
37
+ },
38
+ references: mapReferences(reference.references, snapshotManager, logger),
39
+ };
40
+ })
41
+ .filter(isNotNullOrUndefined);
42
+ };
47
43
  }
48
44
 
49
45
  function decorateGetReferencesAtPosition(
50
- ls: ts.LanguageService,
51
- snapshotManager: AstroSnapshotManager,
52
- logger: Logger
46
+ ls: ts.LanguageService,
47
+ snapshotManager: AstroSnapshotManager,
48
+ logger: Logger
53
49
  ) {
54
- const getReferencesAtPosition = ls.getReferencesAtPosition;
55
- ls.getReferencesAtPosition = (fileName, position) => {
56
- const references = getReferencesAtPosition(fileName, position);
57
- return references && mapReferences(references, snapshotManager, logger);
58
- };
50
+ const getReferencesAtPosition = ls.getReferencesAtPosition;
51
+ ls.getReferencesAtPosition = (fileName, position) => {
52
+ const references = getReferencesAtPosition(fileName, position);
53
+ return references && mapReferences(references, snapshotManager, logger);
54
+ };
59
55
  }
60
56
 
61
57
  function mapReferences(
62
- references: ts.ReferenceEntry[],
63
- snapshotManager: AstroSnapshotManager,
64
- logger: Logger
58
+ references: ts.ReferenceEntry[],
59
+ snapshotManager: AstroSnapshotManager,
60
+ logger: Logger
65
61
  ): 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
- }
62
+ return references
63
+ .map((reference) => {
64
+ const snapshot = snapshotManager.get(reference.fileName);
65
+ if (!isAstroFilePath(reference.fileName) || !snapshot) {
66
+ return reference;
67
+ }
72
68
 
73
- const textSpan = snapshot.getOriginalTextSpan(reference.textSpan);
74
- if (!textSpan) {
75
- return null;
76
- }
69
+ const textSpan = snapshot.getOriginalTextSpan(reference.textSpan);
70
+ if (!textSpan) {
71
+ return null;
72
+ }
77
73
 
78
- logger.debug(
79
- 'Find references; map textSpan: changed',
80
- reference.textSpan,
81
- 'to',
82
- textSpan
83
- );
74
+ logger.debug('Find references; map textSpan: changed', reference.textSpan, 'to', textSpan);
84
75
 
85
- return {
86
- ...reference,
87
- textSpan,
88
- // Spare the work for now
89
- contextSpan: undefined,
90
- originalTextSpan: undefined,
91
- originalContextSpan: undefined
92
- };
93
- })
94
- .filter(isNotNullOrUndefined);
95
- }
76
+ return {
77
+ ...reference,
78
+ textSpan,
79
+ // Spare the work for now
80
+ contextSpan: undefined,
81
+ originalTextSpan: undefined,
82
+ originalContextSpan: undefined,
83
+ };
84
+ })
85
+ .filter(isNotNullOrUndefined);
86
+ }
@@ -1,38 +1,31 @@
1
1
  import type ts from 'typescript/lib/tsserverlibrary';
2
- import { Logger } from '../logger.js';
3
- import { AstroSnapshotManager } from '../astro-snapshots.js';
4
- import { isNotNullOrUndefined, isAstroFilePath } from '../utils.js';
2
+ import type { AstroSnapshotManager } from '../astro-snapshots.js';
3
+ import { isAstroFilePath, isNotNullOrUndefined } from '../utils.js';
5
4
 
6
- export function decorateGetImplementation(
7
- ls: ts.LanguageService,
8
- snapshotManager: AstroSnapshotManager,
9
- logger: Logger
10
- ): void {
11
- const getImplementationAtPosition = ls.getImplementationAtPosition;
12
- ls.getImplementationAtPosition = (fileName, position) => {
13
- const implementation = getImplementationAtPosition(fileName, position);
14
- return implementation
15
- ?.map((impl) => {
16
- if (!isAstroFilePath(impl.fileName)) {
17
- return impl;
18
- }
5
+ export function decorateGetImplementation(ls: ts.LanguageService, snapshotManager: AstroSnapshotManager): void {
6
+ const getImplementationAtPosition = ls.getImplementationAtPosition;
7
+ ls.getImplementationAtPosition = (fileName, position) => {
8
+ const implementation = getImplementationAtPosition(fileName, position);
9
+ return implementation
10
+ ?.map((impl) => {
11
+ if (!isAstroFilePath(impl.fileName)) {
12
+ return impl;
13
+ }
19
14
 
20
- const textSpan = snapshotManager
21
- .get(impl.fileName)
22
- ?.getOriginalTextSpan(impl.textSpan);
23
- if (!textSpan) {
24
- return undefined;
25
- }
15
+ const textSpan = snapshotManager.get(impl.fileName)?.getOriginalTextSpan(impl.textSpan);
16
+ if (!textSpan) {
17
+ return undefined;
18
+ }
26
19
 
27
- return {
28
- ...impl,
29
- textSpan,
30
- // Spare the work for now
31
- contextSpan: undefined,
32
- originalTextSpan: undefined,
33
- originalContextSpan: undefined
34
- };
35
- })
36
- .filter(isNotNullOrUndefined);
37
- };
38
- }
20
+ return {
21
+ ...impl,
22
+ textSpan,
23
+ // Spare the work for now
24
+ contextSpan: undefined,
25
+ originalTextSpan: undefined,
26
+ originalContextSpan: undefined,
27
+ };
28
+ })
29
+ .filter(isNotNullOrUndefined);
30
+ };
31
+ }
@@ -1,43 +1,28 @@
1
1
  import type ts from 'typescript/lib/tsserverlibrary';
2
- import { Logger } from '../logger';
3
- import { AstroSnapshotManager } from '../astro-snapshots.js';
4
- import { isAstroFilePath } from '../utils.js';
2
+ import type { AstroSnapshotManager } from '../astro-snapshots.js';
3
+ import type { Logger } from '../logger';
5
4
  import { decorateCompletions } from './completions.js';
6
5
  import { decorateGetDefinition } from './definition.js';
7
6
  import { decorateDiagnostics } from './diagnostics.js';
7
+ import { decorateGetFileReferences } from './file-references.js';
8
8
  import { decorateFindReferences } from './find-references.js';
9
9
  import { decorateGetImplementation } from './implementation.js';
10
+ import { decorateLineColumnOffset } from './line-column-offset.js';
10
11
  import { decorateRename } from './rename.js';
11
12
 
12
13
  export function decorateLanguageService(
13
- ls: ts.LanguageService,
14
- snapshotManager: AstroSnapshotManager,
15
- logger: Logger
14
+ ls: ts.LanguageService,
15
+ snapshotManager: AstroSnapshotManager,
16
+ logger: Logger
16
17
  ): ts.LanguageService {
17
- patchLineColumnOffset(ls, snapshotManager);
18
- decorateRename(ls, snapshotManager, logger);
19
- decorateDiagnostics(ls, logger);
20
- decorateFindReferences(ls, snapshotManager, logger);
21
- decorateCompletions(ls, logger);
22
- decorateGetDefinition(ls, snapshotManager, logger);
23
- decorateGetImplementation(ls, snapshotManager, logger);
24
- return ls;
25
- }
26
-
27
- function patchLineColumnOffset(ls: ts.LanguageService, snapshotManager: AstroSnapshotManager) {
28
- if (!ls.toLineColumnOffset) {
29
- return;
30
- }
18
+ decorateLineColumnOffset(ls, snapshotManager);
19
+ decorateRename(ls, snapshotManager, logger);
20
+ decorateDiagnostics(ls);
21
+ decorateFindReferences(ls, snapshotManager, logger);
22
+ decorateCompletions(ls, logger);
23
+ decorateGetDefinition(ls, snapshotManager);
24
+ decorateGetImplementation(ls, snapshotManager);
25
+ decorateGetFileReferences(ls, snapshotManager);
31
26
 
32
- // We need to patch this because (according to source, only) getDefinition uses this
33
- const toLineColumnOffset = ls.toLineColumnOffset;
34
- ls.toLineColumnOffset = (fileName, position) => {
35
- if (isAstroFilePath(fileName)) {
36
- const snapshot = snapshotManager.get(fileName);
37
- if (snapshot) {
38
- return snapshot.positionAt(position);
39
- }
40
- }
41
- return toLineColumnOffset(fileName, position);
42
- };
43
- }
27
+ return ls;
28
+ }
@@ -0,0 +1,21 @@
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(ls: ts.LanguageService, snapshotManager: AstroSnapshotManager) {
6
+ if (!ls.toLineColumnOffset) {
7
+ return;
8
+ }
9
+
10
+ // We need to patch this because (according to source, only) getDefinition uses this
11
+ const toLineColumnOffset = ls.toLineColumnOffset;
12
+ ls.toLineColumnOffset = (fileName, position) => {
13
+ if (isAstroFilePath(fileName)) {
14
+ const snapshot = snapshotManager.get(fileName);
15
+ if (snapshot) {
16
+ return snapshot.positionAt(position);
17
+ }
18
+ }
19
+ return toLineColumnOffset(fileName, position);
20
+ };
21
+ }
@@ -1,52 +1,42 @@
1
1
  import type ts from 'typescript/lib/tsserverlibrary';
2
- import { Logger } from '../logger.js';
3
- import { AstroSnapshotManager } from '../astro-snapshots.js';
4
- import { isNotNullOrUndefined, isAstroFilePath } from '../utils.js';
2
+ import type { AstroSnapshotManager } from '../astro-snapshots.js';
3
+ import type { Logger } from '../logger.js';
4
+ import { isAstroFilePath, isNotNullOrUndefined } from '../utils.js';
5
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 = (
13
- fileName,
14
- position,
15
- findInStrings,
16
- findInComments,
17
- providePrefixAndSuffixTextForRename
18
- ) => {
19
- const renameLocations = findRenameLocations(
20
- fileName,
21
- position,
22
- findInStrings,
23
- findInComments,
24
- providePrefixAndSuffixTextForRename
25
- );
26
- return renameLocations
27
- ?.map((renameLocation) => {
28
- const snapshot = snapshotManager.get(renameLocation.fileName);
29
- if (!isAstroFilePath(renameLocation.fileName) || !snapshot) {
30
- return renameLocation;
31
- }
6
+ export function decorateRename(ls: ts.LanguageService, snapshotManager: AstroSnapshotManager, logger: Logger): void {
7
+ const findRenameLocations = ls.findRenameLocations;
8
+ ls.findRenameLocations = (fileName, position, findInStrings, findInComments, providePrefixAndSuffixTextForRename) => {
9
+ const renameLocations = findRenameLocations(
10
+ fileName,
11
+ position,
12
+ findInStrings,
13
+ findInComments,
14
+ providePrefixAndSuffixTextForRename
15
+ );
16
+ return renameLocations
17
+ ?.map((renameLocation) => {
18
+ const snapshot = snapshotManager.get(renameLocation.fileName);
19
+ if (!isAstroFilePath(renameLocation.fileName) || !snapshot) {
20
+ return renameLocation;
21
+ }
32
22
 
33
- // TODO more needed to filter invalid locations, see RenameProvider
34
- const textSpan = snapshot.getOriginalTextSpan(renameLocation.textSpan);
35
- if (!textSpan) {
36
- return null;
37
- }
23
+ // TODO more needed to filter invalid locations, see RenameProvider
24
+ const textSpan = snapshot.getOriginalTextSpan(renameLocation.textSpan);
25
+ if (!textSpan) {
26
+ return null;
27
+ }
38
28
 
39
- const converted = {
40
- ...renameLocation,
41
- textSpan
42
- };
43
- if (converted.contextSpan) {
44
- // Not important, spare the work
45
- converted.contextSpan = undefined;
46
- }
47
- logger.debug('Converted rename location ', converted);
48
- return converted;
49
- })
50
- .filter(isNotNullOrUndefined);
51
- };
52
- }
29
+ const converted = {
30
+ ...renameLocation,
31
+ textSpan,
32
+ };
33
+ if (converted.contextSpan) {
34
+ // Not important, spare the work
35
+ converted.contextSpan = undefined;
36
+ }
37
+ logger.debug('Converted rename location ', converted);
38
+ return converted;
39
+ })
40
+ .filter(isNotNullOrUndefined);
41
+ };
42
+ }
package/src/logger.ts CHANGED
@@ -1,41 +1,37 @@
1
1
  import type ts from 'typescript/lib/tsserverlibrary';
2
2
 
3
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
- }
4
+ constructor(private tsLogService: ts.server.Logger, suppressNonAstroLogs = false, private logDebug = false) {
5
+ if (suppressNonAstroLogs) {
6
+ const log = this.tsLogService.info.bind(this.tsLogService);
7
+ this.tsLogService.info = (s: string) => {
8
+ if (s.startsWith('-Astro Plugin-')) {
9
+ log(s);
10
+ }
11
+ };
12
+ }
13
+ }
18
14
 
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
- }
15
+ log(...args: any[]) {
16
+ const str = args
17
+ .map((arg) => {
18
+ if (typeof arg === 'object') {
19
+ try {
20
+ return JSON.stringify(arg);
21
+ } catch (e) {
22
+ return '[object that cannot by stringified]';
23
+ }
24
+ }
25
+ return arg;
26
+ })
27
+ .join(' ');
28
+ this.tsLogService.info('-Astro Plugin- ' + str);
29
+ }
34
30
 
35
- debug(...args: any[]) {
36
- if (!this.logDebug) {
37
- return;
38
- }
39
- this.log(...args);
40
- }
41
- }
31
+ debug(...args: any[]) {
32
+ if (!this.logDebug) {
33
+ return;
34
+ }
35
+ this.log(...args);
36
+ }
37
+ }