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

Add SvelteTypeScriptImportsResolverProvider #232

Merged
merged 1 commit into from
Jul 22, 2021
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
@@ -0,0 +1,41 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package dev.blachut.svelte.lang.codeInsight

import com.intellij.lang.typescript.modules.TypeScriptNodeReference
import com.intellij.lang.typescript.tsconfig.*
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiManager
import dev.blachut.svelte.lang.SvelteHtmlFileType
import dev.blachut.svelte.lang.isSvelteContext
import dev.blachut.svelte.lang.isTSLangValue
import dev.blachut.svelte.lang.psi.SvelteHtmlFile

const val svelteExtension = ".svelte"
val svelteExtensionsWithDot = arrayOf(svelteExtension)

class SvelteTypeScriptImportsResolverProvider : TypeScriptImportsResolverProvider {
override fun isDynamicFile(project: Project, file: VirtualFile): Boolean {
if (file.fileType != SvelteHtmlFileType.INSTANCE) return false

val psiFile = PsiManager.getInstance(project).findFile(file) as? SvelteHtmlFile ?: return false
val langAttr = psiFile.instanceScript?.getAttribute("lang")?.value
return isTSLangValue(langAttr)
}

override fun useExplicitExtension(extensionWithDot: String): Boolean = extensionWithDot == svelteExtension
override fun getExtensions(): Array<String> = svelteExtensionsWithDot

override fun contributeResolver(project: Project, config: TypeScriptConfig): TypeScriptFileImportsResolver? {
// TODO check if package.json includes svelte
return TypeScriptFileImportsResolverImpl(project, config.resolveContext, TypeScriptNodeReference.TS_PROCESSOR, svelteExtensionsWithDot, listOf(SvelteHtmlFileType.INSTANCE))
}

override fun contributeResolver(project: Project,
context: TypeScriptImportResolveContext,
contextFile: VirtualFile): TypeScriptFileImportsResolver? {
if (!isSvelteContext(contextFile)) return null

return TypeScriptFileImportsResolverImpl(project, context, TypeScriptNodeReference.TS_PROCESSOR, svelteExtensionsWithDot, listOf(SvelteHtmlFileType.INSTANCE))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.intellij.lang.javascript.JSCompositeElementType
import com.intellij.lang.javascript.types.JSEmbeddedContentElementType
import com.intellij.lang.javascript.types.JSExpressionElementType
import com.intellij.lang.javascript.types.JSParameterElementType
import com.intellij.lang.javascript.types.TypeScriptEmbeddedContentElementType
import com.intellij.psi.PsiElement
import com.intellij.psi.tree.IElementType
import dev.blachut.svelte.lang.SvelteJSLanguage
Expand Down Expand Up @@ -34,7 +35,7 @@ object SvelteJSElementTypes {
}
}

val EMBEDDED_CONTENT_MODULE_TS = object : JSEmbeddedContentElementType(SvelteTypeScriptLanguage.INSTANCE, "MOD_SVELTE_TS_") {
val EMBEDDED_CONTENT_MODULE_TS = object : TypeScriptEmbeddedContentElementType(SvelteTypeScriptLanguage.INSTANCE, "MOD_SVELTE_TS_") {
override fun isModule() = true

override fun toModule() = this
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,6 @@

<frameworkIndexingHandler implementation="dev.blachut.svelte.lang.SvelteFrameworkHandler" version="1"/>
<indexedFileTypeProvider implementation="dev.blachut.svelte.lang.SvelteIndexedFileTypeProvider"/>
<tsImportResolver implementation="dev.blachut.svelte.lang.codeInsight.SvelteTypeScriptImportsResolverProvider"/>
</extensions>
</idea-plugin>
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package dev.blachut.svelte.lang.codeInsight
import com.intellij.testFramework.fixtures.BasePlatformTestCase

class SvelteTypeScriptHighlightingTest : BasePlatformTestCase() {
override fun getTestDataPath(): String = "src/test/resources"
override fun getBasePath(): String = "dev/blachut/svelte/lang/codeInsight/tsHighlighting"

override fun setUp() {
super.setUp()
myFixture.enableInspections(*SvelteHighlightingTest.configureDefaultLocalInspectionTools().toTypedArray())
Expand Down Expand Up @@ -44,4 +47,18 @@ class SvelteTypeScriptHighlightingTest : BasePlatformTestCase() {
)
myFixture.testHighlighting()
}

fun testTsconfigDirectAncestorDiscovery() {
val base = basePath + "/" + getTestName(true)
myFixture.configureByFiles("$base/src/App.svelte", "$base/tsconfig.json")

myFixture.testHighlighting()
}

fun testTsconfigIndirectAncestorDiscovery() {
val base = basePath + "/" + getTestName(true)
myFixture.configureByFiles("$base/src/nested/Child.svelte", "$base/tsconfig.json")

myFixture.testHighlighting()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<script lang="ts">
"ABC".includes("A");
["A", "B", "C"].includes("A");
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"compilerOptions": {
"moduleResolution": "node",
"target": "es2017",
/**
Svelte Preprocess cannot figure out whether you have a value or a type, so tell TypeScript
to enforce using `import type` instead of `import` for Types.
*/
"importsNotUsedAsValues": "error",
"isolatedModules": true,
/**
To have warnings/errors of the Svelte compiler at the correct position,
enable source maps by default.
*/
"sourceMap": true,
/** Requests the runtime types from the svelte modules by default. Needed for TS files or else you get errors. */
"types": ["svelte"],
"lib": [
"dom",
"ES2020"
],
"strict": false,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<script lang="ts">
"ABC".includes("A");
["A", "B", "C"].includes("A");
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"compilerOptions": {
"moduleResolution": "node",
"target": "es2017",
/**
Svelte Preprocess cannot figure out whether you have a value or a type, so tell TypeScript
to enforce using `import type` instead of `import` for Types.
*/
"importsNotUsedAsValues": "error",
"isolatedModules": true,
/**
To have warnings/errors of the Svelte compiler at the correct position,
enable source maps by default.
*/
"sourceMap": true,
/** Requests the runtime types from the svelte modules by default. Needed for TS files or else you get errors. */
"types": ["svelte"],
"lib": [
"dom",
"ES2020"
],
"strict": false,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
}