Skip to content
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

Toggle JSX namespace based on svelte vs svelte-native #351

Merged
merged 3 commits into from
Jul 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export class RenameProviderImpl implements RenameProvider {
if (
!renameInfo.canRename ||
renameInfo.kind === ts.ScriptElementKind.jsxAttribute ||
renameInfo.fullDisplayName?.startsWith('JSX.')
renameInfo.fullDisplayName?.includes("JSX.IntrinsicElements")
) {
return null;
}
Expand Down
23 changes: 20 additions & 3 deletions packages/language-server/src/plugins/typescript/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export function createLanguageService(
const svelteModuleLoader = createSvelteModuleLoader(getSnapshot, compilerOptions);

const svelteTsPath = dirname(require.resolve('svelte2tsx'));
const svelteTsxFiles = ['./svelte-shims.d.ts', './svelte-jsx.d.ts'].map((f) =>
const svelteTsxFiles = ['./svelte-shims.d.ts', './svelte-jsx.d.ts', './svelte-native-jsx.d.ts'].map((f) =>
ts.sys.resolvePath(resolve(svelteTsPath, f)),
);

Expand Down Expand Up @@ -162,8 +162,7 @@ export function createLanguageService(
declaration: false,
skipLibCheck: true,
// these are needed to handle the results of svelte2tsx preprocessing:
jsx: ts.JsxEmit.Preserve,
jsxFactory: 'h',
jsx: ts.JsxEmit.Preserve
};

// always let ts parse config to get default compilerOption
Expand Down Expand Up @@ -203,6 +202,24 @@ export function createLanguageService(
...forcedCompilerOptions,
};

// detect which JSX namespace to use (svelte | svelteNative) if not specified or not compatible
if (!compilerOptions.jsxFactory || !compilerOptions.jsxFactory.startsWith("svelte")) {
//default to regular svelte, this causes the usage of the "svelte.JSX" namespace
compilerOptions.jsxFactory = "svelte.createElement";

//override if we detect svelte-native
if (workspacePath) {
try {
const svelteNativePkgInfo = getPackageInfo('svelte-native', workspacePath);
if (svelteNativePkgInfo.path) {
compilerOptions.jsxFactory = "svelteNative.createElement";
}
} catch (e) {
//we stay regular svelte
}
}
}

return { compilerOptions, files };
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from 'vscode-languageserver';
import { CompletionsProviderImpl, CompletionEntryWithIdentifer } from '../../../../src/plugins/typescript/features/CompletionProvider';
import { LSAndTSDocResolver } from '../../../../src/plugins/typescript/LSAndTSDocResolver';
import { sortBy } from 'lodash';

const testDir = join(__dirname, '..');
const testFilesDir = join(testDir, 'testfiles');
Expand Down Expand Up @@ -182,8 +183,11 @@ describe('CompletionProviderImpl', () => {
];
const ignores = ['tsconfig.json', sourceFile];

const testfiles = readdirSync(testFilesDir)
.filter((f) => supportedExtensions.includes(extname(f)) && !ignores.includes(f));
const testfiles = readdirSync(testFilesDir, { withFileTypes: true })
.filter((f) => f.isDirectory()
|| (supportedExtensions.includes(extname(f.name))
&& !ignores.includes(f.name)))
.map(f => f.name);

const completions = await completionProvider.getCompletions(
document,
Expand All @@ -194,7 +198,10 @@ describe('CompletionProviderImpl', () => {
},
);

assert.deepStrictEqual(completions?.items.map(item => item.label), testfiles);
assert.deepStrictEqual(
sortBy(completions?.items.map(item => item.label), x => x),
sortBy(testfiles, x => x)
);
});

it('resolve auto import completion (is first import in file)', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,10 @@ describe('TypescriptPlugin', () => {

assert.deepStrictEqual(diagnostics, []);
});

it('handles svelte native syntax', async () => {
const { plugin, document } = setup('svelte-native/svelte-native.svelte');
const diagnostics = await plugin.getDiagnostics(document);
assert.deepStrictEqual(diagnostics, []);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<page>
<label class="info" horizontalAlignment="center" verticalAlignment="center" textWrap="true">
<formattedString>
<span class="fas" text="&#xf135;" />
<span text=" {message}" />
</formattedString>
</label>
</page>

<script lang="typescript">
let message: string = "Blank Svelte Native App"
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"compilerOptions": {
"jsxFactory": "svelteNative"
}
}
1 change: 1 addition & 0 deletions packages/svelte2tsx/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"README.md",
"LICENSE",
"svelte-jsx.d.ts",
"svelte-native-jsx.d.ts",
"svelte-shims.d.ts"
],
"dependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/svelte2tsx/svelte-jsx.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/


declare namespace JSX {
declare namespace svelte.JSX {

/* svelte specific */
interface ElementClass {
Expand Down
20 changes: 20 additions & 0 deletions packages/svelte2tsx/svelte-native-jsx.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
declare namespace svelteNative.JSX {

/* svelte specific */
interface ElementClass {
$$prop_def: any;
}

interface ElementAttributesProperty {
$$prop_def: any; // specify the property name to use
}

// Add empty IntrinsicAttributes to prevent fallback to the one in the JSX namespace
// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface IntrinsicAttributes {
}

interface IntrinsicElements {
[name: string]: { [name: string]: any };
}
}