-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7706574
commit 5e9be64
Showing
5 changed files
with
205 additions
and
4 deletions.
There are no files selected for viewing
100 changes: 100 additions & 0 deletions
100
src/main/java/dev/blachut/svelte/lang/inspections/SvelteAddImportExecutor.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package dev.blachut.svelte.lang.inspections | ||
|
||
import com.intellij.lang.ecmascript6.psi.ES6ImportDeclaration | ||
import com.intellij.lang.ecmascript6.psi.ES6ImportExportDeclarationPart | ||
import com.intellij.lang.ecmascript6.psi.impl.ES6CreateImportUtil | ||
import com.intellij.lang.ecmascript6.psi.impl.ES6ImportPsiUtil | ||
import com.intellij.lang.ecmascript6.psi.impl.ES6ImportPsiUtil.CreateImportExportInfo | ||
import com.intellij.lang.javascript.DialectDetector | ||
import com.intellij.lang.javascript.formatter.JSCodeStyleSettings | ||
import com.intellij.lang.javascript.psi.JSEmbeddedContent | ||
import com.intellij.lang.typescript.psi.TypeScriptAutoImportUtil | ||
import com.intellij.openapi.editor.Editor | ||
import com.intellij.openapi.util.text.StringUtil | ||
import com.intellij.psi.PsiElement | ||
import com.intellij.psi.XmlElementFactory | ||
import com.intellij.psi.xml.XmlTag | ||
import dev.blachut.svelte.lang.SvelteHTMLLanguage | ||
import dev.blachut.svelte.lang.parsing.js.SvelteJSScriptContentProvider | ||
import dev.blachut.svelte.lang.psi.SvelteHtmlFile | ||
import dev.blachut.svelte.lang.psi.findAncestorScript | ||
|
||
/** | ||
* Adapted from com.intellij.lang.ecmascript6.actions.ES6AddImportExecutor | ||
*/ | ||
class SvelteAddImportExecutor(val editor: Editor?, val place: PsiElement) { | ||
fun createImportOrUseExisting(info: CreateImportExportInfo, externalModule: PsiElement?, quotedModuleName: String): Boolean { | ||
val type = info.importType | ||
val scope = findOrCreateScriptContent() | ||
|
||
return if (tryToUseExistingImport(info, quotedModuleName, externalModule, scope)) { | ||
true | ||
} else { | ||
val importPsi = createTypeScriptOrES6Import(quotedModuleName, info) | ||
if (importPsi == null) { | ||
false | ||
} else { | ||
if (importPsi is ES6ImportDeclaration && type !== ES6ImportPsiUtil.ImportExportType.BARE) { | ||
ES6CreateImportUtil.findPlaceAndInsertES6Import(scope, importPsi, StringUtil.unquoteString(quotedModuleName), editor) | ||
} else { | ||
ES6CreateImportUtil.findPlaceAndInsertAnyImport(scope, importPsi, editor) | ||
} | ||
true | ||
} | ||
} | ||
} | ||
|
||
private fun findOrCreateScriptContent(): JSEmbeddedContent { | ||
val parentScript = findAncestorScript(place) | ||
if (parentScript != null) { | ||
// parent module or instance script | ||
return SvelteJSScriptContentProvider.getJsEmbeddedContent(parentScript)!! | ||
} | ||
|
||
val currentFile = place.containingFile as SvelteHtmlFile | ||
val instanceScript = currentFile.instanceScript | ||
if (instanceScript != null) { | ||
// TODO empty tag | ||
return SvelteJSScriptContentProvider.getJsEmbeddedContent(instanceScript)!! | ||
} | ||
|
||
val elementFactory = XmlElementFactory.getInstance(currentFile.project) | ||
val emptyInstanceScript = elementFactory.createTagFromText("<script>\n</script>", SvelteHTMLLanguage.INSTANCE) | ||
val moduleScript = currentFile.moduleScript | ||
val document = currentFile.document!! | ||
|
||
val script = if (moduleScript != null) { | ||
document.addAfter(emptyInstanceScript, moduleScript) as XmlTag | ||
} else { | ||
document.addBefore(emptyInstanceScript, document.firstChild) as XmlTag | ||
} | ||
|
||
return SvelteJSScriptContentProvider.getJsEmbeddedContent(script)!! | ||
} | ||
|
||
private fun tryToUseExistingImport(info: CreateImportExportInfo, quotedModuleOrNamespaceName: String, externalModule: PsiElement?, scope: PsiElement): Boolean { | ||
val parent: PsiElement = place.parent | ||
if (parent is ES6ImportExportDeclarationPart) { | ||
val grandParent = parent.declaration | ||
if (grandParent is ES6ImportDeclaration && grandParent.getFromClause() == null) { | ||
ES6CreateImportUtil.insertFromClause(parent, grandParent, quotedModuleOrNamespaceName) | ||
return true | ||
} | ||
} | ||
val importType = info.importType | ||
return if (JSCodeStyleSettings.isMergeImports(place) && importType.isES6) { | ||
val possibleImport = ES6ImportPsiUtil.findExistingES6Import(scope, externalModule, quotedModuleOrNamespaceName, info) | ||
possibleImport != null && ES6ImportPsiUtil.tryToAddImportToExistingDeclaration(possibleImport, info) | ||
} else { | ||
false | ||
} | ||
} | ||
|
||
private fun createTypeScriptOrES6Import(externalModuleName: String, info: CreateImportExportInfo): PsiElement? { | ||
return if (!info.importType.isES6 && !DialectDetector.isJavaScript(place)) { | ||
TypeScriptAutoImportUtil.createTypeScriptImport(place, info, externalModuleName) | ||
} else { | ||
ES6ImportPsiUtil.createImportOrExport(place, info, externalModuleName) | ||
} | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
src/main/java/dev/blachut/svelte/lang/inspections/SvelteImportES6ModuleFix.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package dev.blachut.svelte.lang.inspections | ||
|
||
import com.intellij.lang.ecmascript6.psi.impl.ES6ImportPsiUtil.CreateImportExportInfo | ||
import com.intellij.lang.ecmascript6.psi.impl.ES6ImportPsiUtil.ImportExportType | ||
import com.intellij.lang.javascript.modules.ImportES6ModuleFix | ||
import com.intellij.lang.javascript.modules.JSModuleFixDescriptor | ||
import com.intellij.lang.javascript.modules.JSPlaceTail | ||
import com.intellij.openapi.editor.Editor | ||
import com.intellij.psi.PsiElement | ||
|
||
class SvelteImportES6ModuleFix(node: PsiElement, descriptor: JSModuleFixDescriptor, tail: JSPlaceTail?, quoteString: String?, needHint: Boolean) : ImportES6ModuleFix(node, descriptor, tail, quoteString, needHint) { | ||
override fun executeImpl(element: PsiElement, editor: Editor?, scope: PsiElement) { | ||
SvelteAddImportExecutor(editor, element).createImportOrUseExisting(importData, null, myQuotes + this.path + myQuotes) | ||
replaceReferences(element, editor) | ||
} | ||
|
||
private val importData: ImportData | ||
get() { | ||
val importedName = myFixDescriptor.importedName | ||
val type = myFixDescriptor.importType | ||
val exportedName = myFixDescriptor.exportedName | ||
return if (exportedName != null) { | ||
val typeToUse = type ?: ImportExportType.SPECIFIER | ||
if (exportedName == importedName) ImportData(this, importedName, typeToUse) else ImportData(this, exportedName, importedName, typeToUse) | ||
} else if (type != null) { | ||
ImportData(this, importedName, type) | ||
} else if (myTail != null) { | ||
val tail = myTail.strings[0] | ||
ImportData(this, tail ?: importedName, ImportExportType.SPECIFIER) | ||
} else { | ||
ImportData(this, importedName, ImportExportType.IMPORT_BINDING_ALL) | ||
} | ||
} | ||
|
||
private class ImportData : CreateImportExportInfo { | ||
internal constructor(fix: ImportES6ModuleFix?, exportedName: String?, importedName: String, importType: ImportExportType?) : super(exportedName, importedName, importType!!, true, false) | ||
internal constructor(fix: ImportES6ModuleFix, importedName: String, importType: ImportExportType?) : super(null, importedName, importType!!, true, false) | ||
} | ||
|
||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
src/main/java/dev/blachut/svelte/lang/inspections/SvelteModulesSuggester.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package dev.blachut.svelte.lang.inspections | ||
|
||
import com.intellij.codeInspection.LocalQuickFix | ||
import com.intellij.lang.javascript.formatter.JSCodeStyleSettings | ||
import com.intellij.lang.javascript.modules.ES6ModulesSuggester | ||
import com.intellij.lang.javascript.modules.JSModuleFixDescriptor | ||
import com.intellij.lang.javascript.modules.JSPlaceTail | ||
import com.intellij.lang.javascript.modules.ModuleReferenceInfo | ||
import com.intellij.psi.PsiElement | ||
import com.intellij.psi.ResolveResult | ||
import com.intellij.psi.SmartPointerManager | ||
import com.intellij.util.containers.ContainerUtil | ||
import com.intellij.util.containers.MultiMap | ||
import java.util.* | ||
|
||
class SvelteModulesSuggester(info: ModuleReferenceInfo, node: PsiElement) : ES6ModulesSuggester(info, node) { | ||
override fun findFixes(resolveResults: Array<ResolveResult>): MultiMap<PsiElement, LocalQuickFix> { | ||
var descriptors = this.find(resolveResults, false) | ||
if (descriptors.isEmpty()) { | ||
return MultiMap.empty() | ||
} else { | ||
descriptors = ContainerUtil.filter(descriptors) { descriptorx: JSModuleFixDescriptor -> | ||
val fromPath = descriptorx.fromPath | ||
val idx = fromPath.indexOf("node_modules") | ||
idx < 0 || fromPath.indexOf("test", idx) <= 0 && fromPath.indexOf("examples", idx) <= 0 | ||
} | ||
val quoteString = JSCodeStyleSettings.getQuote(myNode) | ||
val list: MutableList<LocalQuickFix?> = ArrayList() | ||
val result = MultiMap.createLinked<PsiElement, LocalQuickFix>() | ||
val size = descriptors.size | ||
val var7: Iterator<*> = descriptors.iterator() | ||
while (var7.hasNext()) { | ||
val descriptor = var7.next() as JSModuleFixDescriptor | ||
val hint = size == 1 && myModuleReferenceInfo.needHint() | ||
list.add(SvelteImportES6ModuleFix(myNode, descriptor, null as JSPlaceTail?, quoteString, hint)) | ||
} | ||
result.putValues(myNode, list) | ||
val parent = myModuleReferenceInfo.parentRef | ||
if (parent != null) { | ||
val project = myNode.project | ||
val secondWordList: MutableList<LocalQuickFix?> = ArrayList(list) | ||
val var10: Iterator<*> = descriptors.iterator() | ||
while (var10.hasNext()) { | ||
val descriptor = var10.next() as JSModuleFixDescriptor | ||
val tail = JSPlaceTail(SmartPointerManager.getInstance(project).createSmartPsiElementPointer(parent), arrayOf(myModuleReferenceInfo.parentName)) | ||
secondWordList.add(SvelteImportES6ModuleFix(parent, descriptor, tail, quoteString, false)) | ||
} | ||
result.putValues(parent, secondWordList) | ||
} | ||
return result | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters