-
Notifications
You must be signed in to change notification settings - Fork 38
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 parsing-only support for typescript #154
Changes from all commits
1495003
b0eedb0
d99fe3d
a01189e
433d1f8
13cc40a
d2aa1e9
c6c8658
cbc2796
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package dev.blachut.svelte.lang | ||
|
||
import com.intellij.lang.javascript.index.IndexedFileTypeProvider | ||
import com.intellij.openapi.fileTypes.FileType | ||
|
||
class SvelteIndexedFileTypeProvider : IndexedFileTypeProvider { | ||
override fun getFileTypesToIndex(): Array<FileType> = arrayOf(SvelteHtmlFileType.INSTANCE) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package dev.blachut.svelte.lang | ||
|
||
import com.intellij.codeInspection.InspectionSuppressor | ||
import com.intellij.codeInspection.SuppressQuickFix | ||
import com.intellij.psi.PsiElement | ||
import dev.blachut.svelte.lang.psi.SvelteHtmlFile | ||
|
||
class SvelteInspectionSuppressor : InspectionSuppressor { | ||
override fun isSuppressedFor(element: PsiElement, toolId: String): Boolean { | ||
if (element.containingFile is SvelteHtmlFile) { | ||
if (toolId == "UnnecessaryLabelJS") { | ||
return element.textMatches("$") | ||
} | ||
if (toolId == "BadExpressionStatementJS") { | ||
return true | ||
} | ||
} | ||
|
||
return false | ||
} | ||
|
||
override fun getSuppressActions(element: PsiElement?, toolId: String): Array<SuppressQuickFix> = emptyArray() | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// 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 | ||
|
||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder | ||
import com.intellij.lang.annotation.AnnotationHolder | ||
import com.intellij.lang.javascript.DialectOptionHolder | ||
import com.intellij.lang.javascript.ecmascript6.TypeScriptAnalysisHandlersFactory | ||
import com.intellij.lang.javascript.ecmascript6.TypeScriptAnnotatingVisitor | ||
import com.intellij.lang.javascript.psi.JSLabeledStatement | ||
import com.intellij.lang.javascript.validation.JSAnnotatingVisitor | ||
import com.intellij.lang.javascript.validation.JSKeywordHighlighterVisitor | ||
import com.intellij.psi.PsiElement | ||
import dev.blachut.svelte.lang.codeInsight.SvelteReactiveDeclarationsUtil | ||
|
||
class SvelteTypeScriptAnalysisHandlersFactory : TypeScriptAnalysisHandlersFactory() { | ||
|
||
override fun createKeywordHighlighterVisitor( | ||
holder: HighlightInfoHolder, | ||
dialectOptionHolder: DialectOptionHolder | ||
): JSKeywordHighlighterVisitor { | ||
return SvelteKeywordHighlighterVisitor(holder) | ||
} | ||
|
||
override fun createAnnotatingVisitor(psiElement: PsiElement, holder: AnnotationHolder): JSAnnotatingVisitor { | ||
return object : TypeScriptAnnotatingVisitor(psiElement, holder) { | ||
override fun visitJSLabeledStatement(node: JSLabeledStatement) { | ||
if (node.label != SvelteReactiveDeclarationsUtil.REACTIVE_LABEL) { | ||
super.visitJSLabeledStatement(node) | ||
} | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package dev.blachut.svelte.lang; | ||
|
||
import com.intellij.lang.DependentLanguage; | ||
import com.intellij.lang.PsiBuilder; | ||
import com.intellij.lang.javascript.DialectOptionHolder; | ||
import com.intellij.lang.javascript.JSLanguageDialect; | ||
import com.intellij.lang.javascript.JavaScriptSupportLoader; | ||
import com.intellij.lang.javascript.parsing.JavaScriptParser; | ||
import dev.blachut.svelte.lang.parsing.ts.SvelteTypeScriptParser; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
/** | ||
* Always nested inside {@link SvelteHTMLLanguage} | ||
*/ | ||
public class SvelteTypeScriptLanguage extends JSLanguageDialect implements DependentLanguage { | ||
public static final SvelteTypeScriptLanguage INSTANCE = new SvelteTypeScriptLanguage(); | ||
|
||
private SvelteTypeScriptLanguage() { | ||
super("SvelteTS", DialectOptionHolder.TS, JavaScriptSupportLoader.TYPESCRIPT); | ||
} | ||
|
||
@Override | ||
public String getFileExtension() { | ||
return "ts"; | ||
} | ||
|
||
@Override | ||
public JavaScriptParser<?, ?, ?, ?> createParser(@NotNull PsiBuilder builder) { | ||
return new SvelteTypeScriptParser(builder); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package dev.blachut.svelte.lang | ||
|
||
import com.intellij.lang.javascript.psi.impl.JSReferenceExpressionImpl | ||
import com.intellij.lang.typescript.TypeScriptSpecificHandlersFactory | ||
import com.intellij.psi.impl.source.resolve.ResolveCache | ||
import dev.blachut.svelte.lang.codeInsight.SvelteTypeScriptReferenceExpressionResolver | ||
|
||
class SvelteTypeScriptSpecificHandlersFactory : TypeScriptSpecificHandlersFactory() { | ||
override fun createReferenceExpressionResolver( | ||
referenceExpression: JSReferenceExpressionImpl, | ||
ignorePerformanceLimits: Boolean | ||
): ResolveCache.PolyVariantResolver<JSReferenceExpressionImpl> { | ||
return SvelteTypeScriptReferenceExpressionResolver(referenceExpression, ignorePerformanceLimits) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// 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.javascript.ecmascript6.TypeScriptReferenceExpressionResolver | ||
import com.intellij.lang.javascript.psi.impl.JSReferenceExpressionImpl | ||
import com.intellij.lang.javascript.psi.resolve.ResolveResultSink | ||
import com.intellij.lang.javascript.psi.resolve.SinkResolveProcessor | ||
import com.intellij.psi.ResolveResult | ||
import dev.blachut.svelte.lang.codeInsight.SvelteJSReferenceExpressionResolver.Companion.resolveImplicits | ||
|
||
class SvelteTypeScriptReferenceExpressionResolver( | ||
referenceExpression: JSReferenceExpressionImpl, | ||
ignorePerformanceLimits: Boolean | ||
) : TypeScriptReferenceExpressionResolver(referenceExpression, ignorePerformanceLimits) { | ||
override fun resolve(expression: JSReferenceExpressionImpl, incompleteCode: Boolean): Array<ResolveResult> { | ||
val resolveImplicits = resolveImplicits(expression) | ||
if (resolveImplicits.isNotEmpty()) return resolveImplicits | ||
|
||
return super.resolve(expression, incompleteCode) | ||
} | ||
|
||
override fun createLocalResolveProcessor(sink: ResolveResultSink): SinkResolveProcessor<ResolveResultSink> { | ||
return SvelteReactiveDeclarationsUtil.SvelteSinkResolveProcessor(myReferencedName, myRef, sink) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package dev.blachut.svelte.lang.parsing.html | ||
|
||
import com.intellij.lang.javascript.DialectDetector | ||
import com.intellij.lang.javascript.ecmascript6.TypeScriptResolveScopeProvider | ||
import com.intellij.lang.javascript.psi.resolve.JSElementResolveScopeProvider | ||
import com.intellij.lang.javascript.psi.util.JSUtils | ||
import com.intellij.lang.typescript.library.TypeScriptLibraryProvider | ||
import com.intellij.openapi.vfs.VirtualFile | ||
import com.intellij.psi.PsiElement | ||
import com.intellij.psi.search.GlobalSearchScope | ||
import com.intellij.psi.xml.XmlFile | ||
import dev.blachut.svelte.lang.SvelteHtmlFileType | ||
|
||
class SvelteElementResolveScopeProvider : JSElementResolveScopeProvider { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. THB I don't understand what this class does |
||
private val tsProvider = object : TypeScriptResolveScopeProvider() { | ||
override fun isApplicable(file: VirtualFile) = true | ||
|
||
override fun restrictByFileType(file: VirtualFile, libraryService: TypeScriptLibraryProvider, moduleAndLibraryScope: GlobalSearchScope): GlobalSearchScope { | ||
return super.restrictByFileType(file, libraryService, moduleAndLibraryScope) | ||
.uniteWith(GlobalSearchScope.getScopeRestrictedByFileTypes(moduleAndLibraryScope, file.fileType)) | ||
} | ||
} | ||
|
||
override fun getElementResolveScope(element: PsiElement): GlobalSearchScope? { | ||
val psiFile = element.containingFile | ||
if (psiFile?.fileType !is SvelteHtmlFileType) return null | ||
if (psiFile !is XmlFile) return null | ||
val scriptTag = JSUtils.findScriptTagContent(psiFile) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Svelte can have two script tags and they could have different languages, this finds first one, is it okay? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can live with it as is. I will try to find a better strategy but I am not sure There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We way we handle this in the language server is to check script and then module script and pick the first lang/type tag we find, so if someone chooses TS in the script tag he will automatically use it in the other one as well - no language mixes. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like a good balance 👍 |
||
|
||
if (scriptTag != null && DialectDetector.isTypeScript(scriptTag)) { | ||
return tsProvider.getResolveScope(psiFile.viewProvider.virtualFile, element.project) | ||
} | ||
return null | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't see problems from this inspection in JS, is this strictly TS related or did I miss something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it fixes useless warning for
$: name