Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/sveltejs/language-tools i…
Browse files Browse the repository at this point in the history
…nto script-kind-node16
  • Loading branch information
jasonlyu123 committed Nov 24, 2024
2 parents 2858300 + fda35fe commit df4c1a7
Show file tree
Hide file tree
Showing 85 changed files with 1,716 additions and 631 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: "18.x"
node-version: "20.x"
cache: pnpm

# Get projects set up
Expand All @@ -31,7 +31,7 @@ jobs:
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: "18.x"
node-version: "20.x"
cache: pnpm

# Lets us use one-liner JSON manipulations the package.json files
Expand All @@ -56,7 +56,7 @@ jobs:
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: "18.x"
node-version: "20.x"
cache: pnpm

# Get projects set up
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/DeployExtensionsProd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: "18.x"
node-version: "20.x"
registry-url: "https://registry.npmjs.org"
cache: pnpm

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/DeploySvelte2tsxProd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: "18.x"
node-version: "20.x"
registry-url: "https://registry.npmjs.org"
cache: pnpm

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/DeploySvelteCheckProd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: "18.x"
node-version: "20.x"
registry-url: "https://registry.npmjs.org"
cache: pnpm

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/DeploySvelteLanguageServerProd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: "18.x"
node-version: "20.x"
registry-url: "https://registry.npmjs.org"
cache: pnpm

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/DeployTypescriptPluginProd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: "18.x"
node-version: "20.x"
registry-url: "https://registry.npmjs.org"
cache: pnpm

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"lint": "prettier --check ."
},
"dependencies": {
"typescript": "^5.6.3"
"typescript": "~5.6.3"
},
"devDependencies": {
"cross-env": "^7.0.2",
Expand Down
4 changes: 4 additions & 0 deletions packages/language-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,10 @@ Enable code actions for Svelte. _Default_: `true`

Enable selection range for Svelte. _Default_: `true`

##### `svelte.plugin.svelte.runesLegacyModeCodeLens.enable`

Whether or not to show a code lens at the top of Svelte files indicating if they are in runes mode or legacy mode. Only visible in Svelte 5 projects. _Default_: `true`

##### `svelte.plugin.svelte.defaultScriptLanguage`

The default language to use when generating new script tags in Svelte. _Default_: `none`
Expand Down
6 changes: 3 additions & 3 deletions packages/language-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
"@types/node": "^18.0.0",
"@types/sinon": "^7.5.2",
"cross-env": "^7.0.2",
"globrex": "^0.1.2",
"mocha": "^9.2.0",
"sinon": "^11.0.0",
"ts-node": "^10.0.0"
Expand All @@ -57,12 +56,13 @@
"chokidar": "^4.0.1",
"estree-walker": "^2.0.1",
"fdir": "^6.2.0",
"globrex": "^0.1.2",
"lodash": "^4.17.21",
"prettier": "~3.3.3",
"prettier-plugin-svelte": "^3.2.6",
"prettier-plugin-svelte": "^3.3.0",
"svelte": "^4.2.19",
"svelte2tsx": "workspace:~",
"typescript": "^5.6.3",
"typescript": "~5.6.3",
"typescript-auto-import-cache": "^0.3.5",
"vscode-css-languageservice": "~6.3.0",
"vscode-html-languageservice": "~5.3.0",
Expand Down
2 changes: 2 additions & 0 deletions packages/language-server/src/ls-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ const defaultLSConfig: LSConfig = {
hover: { enable: true },
codeActions: { enable: true },
selectionRange: { enable: true },
runesLegacyModeCodeLens: { enable: true },
defaultScriptLanguage: 'none'
}
};
Expand Down Expand Up @@ -188,6 +189,7 @@ export interface LSSvelteConfig {
selectionRange: {
enable: boolean;
};
runesLegacyModeCodeLens: { enable: boolean };
defaultScriptLanguage: 'none' | 'ts';
}

Expand Down
5 changes: 3 additions & 2 deletions packages/language-server/src/plugins/PluginHost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -633,12 +633,13 @@ export class PluginHost implements LSProvider, OnWatchFileChanges {
throw new Error('Cannot call methods on an unopened document');
}

return await this.execute<CodeLens[]>(
const result = await this.execute<CodeLens[]>(
'getCodeLens',
[document],
ExecuteMode.FirstNonNull,
ExecuteMode.Collect,
'smart'
);
return flatten(result.filter(Boolean));
}

async getFoldingRanges(textDocument: TextDocumentIdentifier): Promise<FoldingRange[]> {
Expand Down
29 changes: 29 additions & 0 deletions packages/language-server/src/plugins/html/dataProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,12 @@ const svelteTags: ITagData[] = [
}
]
},
{
name: 'svelte:html',
description:
'This element allows you to add properties and listeners to events on `document.documentElement`. This is useful for attributes such as `lang` which influence how the browser interprets the content.',
attributes: []
},
{
name: 'svelte:document',
description:
Expand Down Expand Up @@ -296,6 +302,17 @@ const svelteTags: ITagData[] = [
'Named slots allow consumers to target specific areas. They can also have fallback content.'
}
]
},
{
name: 'svelte:boundary',
description:
'Represents a boundary in the application. Can catch errors and show fallback UI',
attributes: [
{
name: 'onerror',
description: 'Called when an error occured within the boundary'
}
]
}
];

Expand Down Expand Up @@ -419,6 +436,18 @@ export const svelteHtmlDataProvider = newHTMLDataProvider('svelte-builtin', {
})) ?? []
});

const originalProvideAttributes =
svelteHtmlDataProvider.provideAttributes.bind(svelteHtmlDataProvider);

svelteHtmlDataProvider.provideAttributes = (tag: string) => {
if (tag === 'svelte:boundary' || tag === 'svelte:options') {
// We don't want the global attributes for these tags
return svelteTags.find((t) => t.name === tag)?.attributes ?? [];
}

return originalProvideAttributes(tag);
};

function isEvent(attr: IAttributeData) {
return attr.name.startsWith('on');
}
Expand Down
10 changes: 5 additions & 5 deletions packages/language-server/src/plugins/svelte/SvelteDocument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ type PositionMapper = Pick<DocumentMapper, 'getGeneratedPosition' | 'getOriginal
* Represents a text document that contains a svelte component.
*/
export class SvelteDocument {
private transpiledDoc: ITranspiledSvelteDocument | undefined;
private compileResult: SvelteCompileResult | undefined;
private transpiledDoc: Promise<ITranspiledSvelteDocument> | undefined;
private compileResult: Promise<SvelteCompileResult> | undefined;
private svelteVersion: [number, number] | undefined;

public script: TagInformation | null;
Expand Down Expand Up @@ -76,12 +76,12 @@ export class SvelteDocument {
const [major, minor] = this.getSvelteVersion();

if (major > 3 || (major === 3 && minor >= 32)) {
this.transpiledDoc = await TranspiledSvelteDocument.create(
this.transpiledDoc = TranspiledSvelteDocument.create(
this.parent,
await this.config
);
} else {
this.transpiledDoc = await FallbackTranspiledSvelteDocument.create(
this.transpiledDoc = FallbackTranspiledSvelteDocument.create(
this.parent,
(await this.config)?.preprocess
);
Expand All @@ -92,7 +92,7 @@ export class SvelteDocument {

async getCompiled(): Promise<SvelteCompileResult> {
if (!this.compileResult) {
this.compileResult = await this.getCompiledWith((await this.config)?.compilerOptions);
this.compileResult = this.getCompiledWith((await this.config)?.compilerOptions);
}

return this.compileResult;
Expand Down
17 changes: 13 additions & 4 deletions packages/language-server/src/plugins/svelte/SveltePlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ export class SveltePlugin
constructor(private configManager: LSConfigManager) {}

async getCodeLens(document: Document): Promise<CodeLens[] | null> {
if (!this.featureEnabled('runesLegacyModeCodeLens')) return null;

const doc = await this.getSvelteDoc(document);
if (!doc.isSvelte5) return null;

Expand Down Expand Up @@ -125,11 +127,9 @@ export class SveltePlugin
/**
* Prettier v2 can't use v3 plugins and vice versa. Therefore, we need to check
* which version of prettier is used in the workspace and import the correct
* version of the Svelte plugin. If user uses Prettier >= 3 and has no Svelte plugin
* then fall back to our built-in versions which are both v2 and compatible with
* version of the Svelte plugin. If user uses Prettier < 3 and has no Svelte plugin
* then fall back to our built-in versions which are both v3 and compatible with
* each other.
* TODO switch this around at some point to load Prettier v3 by default because it's
* more likely that users have that installed.
*/
const importFittingPrettier = async () => {
const getConfig = async (p: any) => {
Expand Down Expand Up @@ -204,6 +204,15 @@ export class SveltePlugin
return [];
}

if (isFallback || !(await hasSveltePluginLoaded(prettier, resolvedPlugins))) {
// If the user uses Svelte 5 but doesn't have prettier installed, we need to provide
// the compiler path to the plugin so it can use its parser method; else it will crash.
const svelteCompilerInfo = getPackageInfo('svelte', filePath);
if (svelteCompilerInfo.version.major >= 5) {
config.svelte5CompilerPath = svelteCompilerInfo.path + '/compiler';
}
}

// Prettier v3 format is async, v2 is not
const formattedCode = await prettier.format(document.getText(), {
...config,
Expand Down
22 changes: 15 additions & 7 deletions packages/language-server/src/plugins/svelte/features/SvelteTags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Await blocks allow you to branch on the three possible states of a Promise — p
\`{#await expression}...{:then name}...{/await}\`\\
\`{#await expression then name}...{/await}\`\\
\\
https://svelte.dev/docs#template-syntax-await
https://svelte.dev/docs/svelte/await
`,
each: `\`{#each ...}\`\\
Iterating over lists of values can be done with an each block.
Expand All @@ -33,7 +33,7 @@ Iterating over lists of values can be done with an each block.
\`{#each expression as name, index (key)}...{/each}\`\\
\`{#each expression as name}...{:else}...{/each}\`\\
\\
https://svelte.dev/docs#template-syntax-each
https://svelte.dev/docs/svelte/each
`,
if: `\`{#if ...}\`\\
Content that is conditionally rendered can be wrapped in an if block.
Expand All @@ -42,7 +42,7 @@ Content that is conditionally rendered can be wrapped in an if block.
\`{#if expression}...{:else if expression}...{/if}\`\\
\`{#if expression}...{:else}...{/if}\`\\
\\
https://svelte.dev/docs#template-syntax-if
https://svelte.dev/docs/svelte/if
`,
key: `\`{#key expression}...{/key}\`\\
Key blocks destroy and recreate their contents when the value of an expression changes.\\
Expand All @@ -51,14 +51,22 @@ When used around components, this will cause them to be reinstantiated and reini
#### Usage:
\`{#key expression}...{/key}\`\\
\\
https://svelte.dev/docs#template-syntax-key
https://svelte.dev/docs/svelte/key
`,
snippet: `\`{#snippet identifier(parameter)}...{/snippet}\`\\
Snippets allow you to create reusable UI blocks you can render with the {@render ...} tag.
They also function as slot props for components.
#### Usage:
\`{#snippet identifier(parameter)}...{/snippet}\`\\
\\
https://svelte.dev/docs/svelte/snippet
`,
render: `\`{@render ...}\`\\
Renders a snippet with the given parameters.
#### Usage:
\`{@render identifier(parameter)}\`\\
\\
https://svelte.dev/docs/svelte/@render
`,
html:
`\`{@html ...}\`\\
Expand All @@ -72,7 +80,7 @@ If the data comes from an untrusted source, you must sanitize it, ` +
#### Usage:
\`{@html expression}\`\\
\\
https://svelte.dev/docs#template-syntax-html
https://svelte.dev/docs/svelte/@html
`,
debug:
`\`{@debug ...}\`\\
Expand All @@ -84,14 +92,14 @@ It accepts a comma-separated list of variable names (not arbitrary expressions).
\`{@debug}\`
\`{@debug var1, var2, ..., varN}\`\\
\\
https://svelte.dev/docs#template-syntax-debug
https://svelte.dev/docs/svelte/@debug
`,
const: `\`{@const ...}\`\\
Defines a local constant}\\
#### Usage:
\`{@const a = b + c}\`\\
\\
https://svelte.dev/docs/special-tags#const
https://svelte.dev/docs/svelte/@const
`
};

Expand Down
18 changes: 12 additions & 6 deletions packages/language-server/src/plugins/typescript/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ async function createLanguageService(
: undefined;

const changedFilesForExportCache = new Set<string>();
const svelteTsxFiles = getSvelteShimFiles();
const svelteTsxFilesToOriginalCasing = getSvelteShimFiles();

let languageServiceReducedMode = false;
let projectVersion = 0;
Expand Down Expand Up @@ -701,7 +701,10 @@ async function createLanguageService(
...clientFiles.filter(
(file) => !canonicalProjectFileNames.has(getCanonicalFileName(file))
),
...svelteTsxFiles
// Use original casing here, too: people could have their VS Code extensions in a case insensitive
// folder but their project in a case sensitive one; and if we copy the shims into the case sensitive
// part it would break when canonicalizing it.
...svelteTsxFilesToOriginalCasing.values()
])
);
}
Expand Down Expand Up @@ -1221,14 +1224,17 @@ async function createLanguageService(
svelteTsPath,
docContext.isSvelteCheck ? undefined : tsconfigPath || workspacePath
);
const result = new FileSet(tsSystem.useCaseSensitiveFileNames);
const pathToOriginalCasing = new Map<string, string>();
for (const file of svelteTsxFiles) {
const normalizedPath = normalizePath(file);
pathToOriginalCasing.set(getCanonicalFileName(normalizedPath), normalizedPath);
}

svelteTsxFiles.forEach((f) => result.add(normalizePath(f)));
return result;
return pathToOriginalCasing;
}

function isShimFiles(filePath: string) {
return svelteTsxFiles.has(normalizePath(filePath));
return svelteTsxFilesToOriginalCasing.has(getCanonicalFileName(normalizePath(filePath)));
}
}

Expand Down
Loading

0 comments on commit df4c1a7

Please sign in to comment.