diff --git a/build.gradle.kts b/build.gradle.kts index 110b2f0..73325a6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -36,7 +36,7 @@ repositories { } intellij { - version.set("IC-2023.2.5") + version.set("IU-2023.2.5") sandboxDir.set("idea-sandbox") plugins.set(listOf("java")) } diff --git a/src/main/grammar/main.bnf b/src/main/grammar/main.bnf index a5c8ecf..e4f2f20 100644 --- a/src/main/grammar/main.bnf +++ b/src/main/grammar/main.bnf @@ -66,11 +66,11 @@ // Document ::= DocumentElement* private recoverTopElement ::= !('component' | 'struct' | 'enum' | 'global'| 'export'|'import' ) -private DocumentElement ::= Import | Struct |Export | Enum | GlobalSingleton | Component { +private DocumentElement ::= Import | Struct | Enum | GlobalSingleton | Component | Export { recoverWhile=recoverTopElement } -GlobalSingleton ::= GlobalKeyword ComponentName ComponentBody { - pin=1 +GlobalSingleton ::= ExportKeyword? GlobalKeyword ComponentName ComponentBody { + pin=2 implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"] mixin="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementMixinImpl" } @@ -79,30 +79,32 @@ Import ::= ImportKeyword ImportElement? ModuleLocation';'{ pin=1 } -private ImportElement ::= '{' ImportedIdentifier (',' ImportedIdentifier)* ','? '}' FromKeyword { +private ImportElement ::= '{' ImportedSpecifier (',' ImportedSpecifier)* ','? '}' FromKeyword { pin=1 } // ABc as Def -ImportedIdentifier ::= ReferenceIdentifier ImportAlias?{ +ImportedSpecifier ::= ReferenceIdentifier ImportAlias?{ pin=1 recoverWhile=AliasNameRecover } private AliasNameRecover::=!(','|'}'|';') -private ImportAlias ::= AsKeyword InternalName { +ImportAlias ::= AsKeyword InternalName { pin=1 + implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"] + mixin="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementMixinImpl" } //Struct 定义 -Struct ::= StructKeyword TypeName (':=')? StructBody { - pin=1 +Struct ::= ExportKeyword? StructKeyword TypeName (':=')? StructBody { + pin=2 } private StructBody ::= '{' FieldDeclarations? '}'{ pin=1 } //EnumDeclaration -Enum ::= EnumKeyword EnumName '{' (EnumValue (','EnumValue)*','? )? '}'{ - pin=1 +Enum ::= ExportKeyword? EnumKeyword EnumName '{' (EnumValue (','EnumValue)*','? )? '}'{ + pin=2 implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"] mixin="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementMixinImpl" } @@ -111,15 +113,17 @@ Enum ::= EnumKeyword EnumName '{' (EnumValue (','EnumValue)*','? )? '}'{ Export ::= ExportKeyword ExportElement { pin=1 } -private ExportElement ::= ExportType | Struct| Component | ExportModule | GlobalSingleton|Enum +private ExportElement ::= ExportType | ExportModule -ExportType ::= '{' ExportIdentifier (','ExportIdentifier)* ','? '}'{ +ExportType ::= '{' ExportSpecifier (','ExportSpecifier)* ','? '}'{ pin=1 } -ExportIdentifier ::= ReferenceIdentifier ExportAlias?{ - +ExportSpecifier::= ReferenceIdentifier ExportAlias?{ + recoverWhile=AliasNameRecover + implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"] + mixin="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementMixinImpl" } -private ExportAlias ::= AsKeyword ExternalName{ +ExportAlias ::= AsKeyword ExternalName{ pin=1 } ExportModule ::= '*' FromKeyword ModuleLocation ';'{ @@ -131,8 +135,8 @@ ExportModule ::= '*' FromKeyword ModuleLocation ';'{ //Old syntax //private LegacyComponent ::=(GlobalKeyword ComponentName ':=' ComponentName? ComponentBody)| ('global'? SubComponent) -Component ::= ComponentKeyword ComponentName InheritDeclaration? ComponentBody { - pin=1 +Component ::= ExportKeyword? ComponentKeyword ComponentName InheritDeclaration? ComponentBody { + pin=2 implements=[ "me.zhouxi.slint.lang.psi.SlintPsiNamedElement" "com.intellij.psi.StubBasedPsiElement" @@ -517,10 +521,7 @@ FunctionName ::= GenericIdentifier ComponentName ::=GenericIdentifier -InternalName ::= GenericIdentifier{ - mixin="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementMixinImpl" - implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"] -} +InternalName ::= GenericIdentifier PropertyName ::= GenericIdentifier @@ -530,10 +531,7 @@ EnumName ::= GenericIdentifier EnumValue ::=GenericIdentifier -ExternalName ::=GenericIdentifier{ - mixin="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementMixinImpl" - implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"] -} +ExternalName ::=GenericIdentifier ReferenceIdentifier::=GenericIdentifier{ mixin="me.zhouxi.slint.lang.psi.impl.SlintReferencedIdentifierMixinImpl" diff --git a/src/main/kotlin/me/zhouxi/slint/completion/SlintCompletionContributor.kt b/src/main/kotlin/me/zhouxi/slint/completion/SlintCompletionContributor.kt index 0d32353..07e1b01 100644 --- a/src/main/kotlin/me/zhouxi/slint/completion/SlintCompletionContributor.kt +++ b/src/main/kotlin/me/zhouxi/slint/completion/SlintCompletionContributor.kt @@ -4,6 +4,9 @@ import com.intellij.codeInsight.completion.* import com.intellij.codeInsight.lookup.LookupElementBuilder import com.intellij.icons.AllIcons import com.intellij.patterns.PlatformPatterns +import com.intellij.psi.PsiClass +import com.intellij.psi.search.GlobalSearchScope +import com.intellij.psi.stubs.StubIndex import com.intellij.psi.util.childrenOfType import com.intellij.psi.util.parentOfType import com.intellij.util.ProcessingContext @@ -15,6 +18,7 @@ import me.zhouxi.slint.lang.psi.SlintPsiUtils.InternalTypes import me.zhouxi.slint.lang.psi.SlintTypes import me.zhouxi.slint.lang.psi.utils.exportedElements import me.zhouxi.slint.lang.psi.utils.inheritDeclaredElements +import me.zhouxi.slint.stubs.StubKeys import me.zhouxi.slint.stubs.types.SlintFileElementType class SlintCompletionContributor : CompletionContributor() { @@ -57,19 +61,17 @@ class SlintCompletionContributor : CompletionContributor() { context: ProcessingContext, result: CompletionResultSet ) { + val project = parameters.position.project + val components = StubIndex.getInstance().getAllKeys(StubKeys.Component, project).map { + LookupElementBuilder.create(it).withIcon(AllIcons.Nodes.Class) + } + result.addAllElements(components) result.addAllElements(ElementKeywords) - val component = parameters.position.parentOfType() ?: return - val elements = component.inheritDeclaredElements() - for (element in elements) { - result.addElement(LookupElementBuilder.create(element).withIcon(AllIcons.Nodes.Property)) - } - val file = component.containingFile as SlintFile - val array = file.childrenOfType() - .mapNotNull { it.moduleLocation?.reference?.resolve() as SlintFile? } - .flatMap { it.exportedElements() } - for (element in array) { - result.addElement(LookupElementBuilder.create(element).withIcon(AllIcons.Nodes.Class)) + val currentComponent = parameters.position.parentOfType() ?: return + val elements = currentComponent.inheritDeclaredElements().map { + LookupElementBuilder.create(it).withIcon(AllIcons.Nodes.Property) } + result.addAllElements(elements) } }) } diff --git a/src/main/kotlin/me/zhouxi/slint/lang/psi/impl/SlintPsiNamedElementMixinImpl.kt b/src/main/kotlin/me/zhouxi/slint/lang/psi/impl/SlintPsiNamedElementMixinImpl.kt index 5d5a6bb..dd60fa7 100644 --- a/src/main/kotlin/me/zhouxi/slint/lang/psi/impl/SlintPsiNamedElementMixinImpl.kt +++ b/src/main/kotlin/me/zhouxi/slint/lang/psi/impl/SlintPsiNamedElementMixinImpl.kt @@ -14,7 +14,7 @@ import me.zhouxi.slint.lang.psi.SlintPsiNamedElement abstract class SlintPsiNamedElementMixinImpl(node: ASTNode) : SlintPsiElementImpl(node), SlintPsiNamedElement { override fun getNameIdentifier(): PsiElement? { - return findChildByClass(SlintNamed::class.java) + return findChildByClass(SlintNamed::class.java) ?: this } override fun getName(): String? { @@ -26,7 +26,12 @@ abstract class SlintPsiNamedElementMixinImpl(node: ASTNode) : SlintPsiElementImp } override fun getTextOffset(): Int { - return nameIdentifier?.textOffset ?: super.getTextOffset() + val identifier = nameIdentifier + return if (identifier == this) { + return super.getTextOffset() + } else { + identifier!!.textOffset + } } @Throws(IncorrectOperationException::class) diff --git a/src/main/kotlin/me/zhouxi/slint/lang/psi/utils/SlintFileUtils.kt b/src/main/kotlin/me/zhouxi/slint/lang/psi/utils/SlintFileUtils.kt index 2cf4bc2..d40b6b8 100644 --- a/src/main/kotlin/me/zhouxi/slint/lang/psi/utils/SlintFileUtils.kt +++ b/src/main/kotlin/me/zhouxi/slint/lang/psi/utils/SlintFileUtils.kt @@ -7,29 +7,29 @@ import me.zhouxi.slint.lang.psi.* fun SlintExport.exportedElements(): List { val list = mutableListOf() - this.exportType?.exportIdentifierList?.forEach { - if (it.externalName == null) { - val component = it.referenceIdentifier.reference?.resolve() as SlintComponent? - component?.let { list.add(component) } - } else { - list.add(it.externalName!!) - } - } - this.component?.let { list.add(it) } - this.globalSingleton?.let { list.add(it) } - val file = this.exportModule?.moduleLocation?.reference?.resolve() as SlintFile? ?: return list - val exports = file.childrenOfType() - //TODO recursion error - exports.forEach { list.addAll(it.exportedElements()) } +// this.exportType?.exportIdentifierList?.forEach { +// if (it.externalName == null) { +// val component = it.referenceIdentifier.reference?.resolve() as SlintComponent? +// component?.let { list.add(component) } +// } else { +// list.add(it.externalName!!) +// } +// } +// this.component?.let { list.add(it) } +// this.globalSingleton?.let { list.add(it) } +// val file = this.exportModule?.moduleLocation?.reference?.resolve() as SlintFile? ?: return list +// val exports = file.childrenOfType() +// //TODO recursion error +// exports.forEach { list.addAll(it.exportedElements()) } return list } fun SlintImport.importedElements(): List { val list = mutableListOf() - this.importedIdentifierList.forEach { identifier -> - list.add(identifier.referenceIdentifier) - identifier.internalName?.let { list.add(it) } - } +// this.importedIdentifierList.forEach { identifier -> +// list.add(identifier.referenceIdentifier) +// identifier.internalName?.let { list.add(it) } +// } return list } diff --git a/src/main/kotlin/me/zhouxi/slint/reference/SlintReferenceContributor.kt b/src/main/kotlin/me/zhouxi/slint/reference/SlintReferenceContributor.kt index 79b5bd0..7d9b980 100644 --- a/src/main/kotlin/me/zhouxi/slint/reference/SlintReferenceContributor.kt +++ b/src/main/kotlin/me/zhouxi/slint/reference/SlintReferenceContributor.kt @@ -22,8 +22,8 @@ class SlintReferenceContributor : PsiReferenceContributor() { psiElement(SubComponent), psiElement(Component), psiElement(InheritDeclaration), - psiElement(ImportedIdentifier), - psiElement(ExportIdentifier) +// psiElement(ImportedIdentifier), +// psiElement(ExportIdentifier) ) ), ComponentReferenceProvider() diff --git a/src/main/kotlin/me/zhouxi/slint/reference/provider/ComponentReferenceProvider.kt b/src/main/kotlin/me/zhouxi/slint/reference/provider/ComponentReferenceProvider.kt index 3751fb1..89c2a2c 100644 --- a/src/main/kotlin/me/zhouxi/slint/reference/provider/ComponentReferenceProvider.kt +++ b/src/main/kotlin/me/zhouxi/slint/reference/provider/ComponentReferenceProvider.kt @@ -28,12 +28,6 @@ class ComponentReferenceProvider : PsiReferenceProvider() { if (component != null) { return component } - // TODO psiTreeUtils - //然后是导出的组件 maybe component or externalName - val externalElement = file.exportedElements().firstOrNull { it.textMatches(element) } - if (externalElement != null) { - return externalElement - } //maybe internalName or referencedIdentifier; val element = file.importedElements().firstOrNull { it.textMatches(element) } ?: return null if (element is SlintPsiReferencedIdentifier) { @@ -44,13 +38,5 @@ class ComponentReferenceProvider : PsiReferenceProvider() { } return element } - - override fun getVariants(): Array { - val file = element.containingFile as SlintFile - val array: Array = file.childrenOfType() - .mapNotNull { it.moduleLocation?.reference?.resolve() as SlintFile? } - .flatMap { it.exportedElements() }.toTypedArray() - return array - } } } diff --git a/src/main/kotlin/me/zhouxi/slint/reference/provider/InternalNameReferenceProvider.kt b/src/main/kotlin/me/zhouxi/slint/reference/provider/InternalNameReferenceProvider.kt deleted file mode 100644 index b4cbb17..0000000 --- a/src/main/kotlin/me/zhouxi/slint/reference/provider/InternalNameReferenceProvider.kt +++ /dev/null @@ -1,29 +0,0 @@ -package me.zhouxi.slint.reference.provider - -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiReference -import com.intellij.psi.PsiReferenceBase -import com.intellij.psi.PsiReferenceProvider -import com.intellij.psi.util.parentOfType -import com.intellij.util.ProcessingContext -import me.zhouxi.slint.lang.psi.SlintFile -import me.zhouxi.slint.lang.psi.SlintImport -import me.zhouxi.slint.lang.psi.SlintInternalName -import me.zhouxi.slint.lang.psi.utils.exportedElements - -/** - * @author zhouxi 2024/5/17 - */ -class InternalNameReferenceProvider : PsiReferenceProvider() { - override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array { - return arrayOf(InternalNameReference(element as SlintInternalName)) - } - - class InternalNameReference(element: SlintInternalName) : PsiReferenceBase(element) { - override fun resolve(): PsiElement? { - val slintImport = element.parentOfType() ?: return null - val slintFile = slintImport.moduleLocation?.reference?.resolve() as? SlintFile ?: return null - return slintFile.exportedElements().firstOrNull { it.textMatches(element) } - } - } -} diff --git a/src/main/kotlin/me/zhouxi/slint/stubs/impl/SlintFileStubImpl.kt b/src/main/kotlin/me/zhouxi/slint/stubs/impl/SlintFileStubImpl.kt index 4eaccaf..a31a1b4 100644 --- a/src/main/kotlin/me/zhouxi/slint/stubs/impl/SlintFileStubImpl.kt +++ b/src/main/kotlin/me/zhouxi/slint/stubs/impl/SlintFileStubImpl.kt @@ -2,16 +2,18 @@ package me.zhouxi.slint.stubs.impl import com.intellij.psi.stubs.PsiFileStubImpl import com.intellij.psi.tree.IStubFileElementType +import me.zhouxi.slint.lang.psi.SlintComponent import me.zhouxi.slint.lang.psi.SlintFile +import me.zhouxi.slint.lang.psi.SlintTypes import me.zhouxi.slint.stubs.stub.SlintFileStub +import me.zhouxi.slint.stubs.types.SlintComponentStubType import me.zhouxi.slint.stubs.types.SlintFileElementType /** * @author zhouxi 2024/5/23 */ -class SlintFileStubImpl(file: SlintFile) : PsiFileStubImpl(file), SlintFileStub { +class SlintFileStubImpl(file: SlintFile?) : PsiFileStubImpl(file), SlintFileStub { + + override fun getType() = SlintFileElementType - override fun getType(): IStubFileElementType<*> { - return SlintFileElementType - } } diff --git a/src/main/kotlin/me/zhouxi/slint/stubs/index/ComponentNameIndex.kt b/src/main/kotlin/me/zhouxi/slint/stubs/index/ComponentNameIndex.kt index 463d55c..d537068 100644 --- a/src/main/kotlin/me/zhouxi/slint/stubs/index/ComponentNameIndex.kt +++ b/src/main/kotlin/me/zhouxi/slint/stubs/index/ComponentNameIndex.kt @@ -6,7 +6,5 @@ import me.zhouxi.slint.lang.psi.SlintComponent import me.zhouxi.slint.stubs.StubKeys class ComponentNameIndex : StringStubIndexExtension() { - override fun getKey(): StubIndexKey { - return StubKeys.Component - } + override fun getKey() = StubKeys.Component } diff --git a/src/main/kotlin/me/zhouxi/slint/stubs/stub/SlintFileStub.kt b/src/main/kotlin/me/zhouxi/slint/stubs/stub/SlintFileStub.kt index 40d55e4..be1651e 100644 --- a/src/main/kotlin/me/zhouxi/slint/stubs/stub/SlintFileStub.kt +++ b/src/main/kotlin/me/zhouxi/slint/stubs/stub/SlintFileStub.kt @@ -1,7 +1,15 @@ -package me.zhouxi.slint.stubs.stub; +package me.zhouxi.slint.stubs.stub -import com.intellij.psi.stubs.PsiFileStub; -import me.zhouxi.slint.lang.psi.SlintFile; +import com.intellij.psi.stubs.PsiFileStub +import me.zhouxi.slint.lang.psi.SlintComponent +import me.zhouxi.slint.lang.psi.SlintFile +import me.zhouxi.slint.lang.psi.SlintTypes +import me.zhouxi.slint.stubs.types.SlintFileElementType -public interface SlintFileStub extends PsiFileStub { +interface SlintFileStub : PsiFileStub { + + val components: Array + get() = getChildrenByType(SlintTypes.Component) { + arrayOfNulls(it) + } } diff --git a/src/main/kotlin/me/zhouxi/slint/stubs/types/SlintComponentStubType.kt b/src/main/kotlin/me/zhouxi/slint/stubs/types/SlintComponentStubType.kt index ea05abe..18e5acb 100644 --- a/src/main/kotlin/me/zhouxi/slint/stubs/types/SlintComponentStubType.kt +++ b/src/main/kotlin/me/zhouxi/slint/stubs/types/SlintComponentStubType.kt @@ -4,20 +4,20 @@ import com.intellij.lang.ASTNode import com.intellij.lang.LighterAST import com.intellij.lang.LighterASTNode import com.intellij.lang.LighterASTTokenNode -import com.intellij.lang.TreeBackedLighterAST +import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement +import com.intellij.psi.impl.search.JavaSourceFilterScope +import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.stubs.* import com.intellij.psi.util.parentOfType import me.zhouxi.slint.lang.SlintLanguage import me.zhouxi.slint.lang.psi.SlintComponent import me.zhouxi.slint.lang.psi.SlintExport -import me.zhouxi.slint.lang.psi.SlintTypes.ComponentName -import me.zhouxi.slint.lang.psi.SlintTypes.Export +import me.zhouxi.slint.lang.psi.SlintTypes.* import me.zhouxi.slint.lang.psi.impl.SlintComponentImpl import me.zhouxi.slint.stubs.StubKeys import me.zhouxi.slint.stubs.impl.SlintComponentStubImpl import me.zhouxi.slint.stubs.stub.SlintComponentStub -import org.mozilla.javascript.ast.AstNode import java.io.IOException /** @@ -37,7 +37,7 @@ class SlintComponentStubType(debugName: String) : return SlintComponentStubImpl( parentStub, this, - psi.parentOfType() != null, + psi.exportKeyword != null, psi.componentName!!.text ) } @@ -60,15 +60,7 @@ class SlintComponentStubType(debugName: String) : } override fun createStub(tree: LighterAST, node: LighterASTNode, parentStub: StubElement<*>): SlintComponentStub { - var exported = false - var parent = tree.getParent(node) - while (parent != null) { - if (parent.tokenType == Export) { - exported = true - break - } - parent = tree.getParent(parent) - } + val exported = tree.getChildren(node).any { it.tokenType == ExportKeyword } val identifier = tree.getChildren(node).first { it.tokenType == ComponentName } val token = tree.getChildren(identifier)[0] as LighterASTTokenNode diff --git a/src/main/kotlin/me/zhouxi/slint/stubs/types/SlintFileElementType.kt b/src/main/kotlin/me/zhouxi/slint/stubs/types/SlintFileElementType.kt index 254202f..91b3211 100644 --- a/src/main/kotlin/me/zhouxi/slint/stubs/types/SlintFileElementType.kt +++ b/src/main/kotlin/me/zhouxi/slint/stubs/types/SlintFileElementType.kt @@ -1,13 +1,19 @@ package me.zhouxi.slint.stubs.types +import com.intellij.psi.stubs.StubElement +import com.intellij.psi.stubs.StubInputStream import com.intellij.psi.tree.ILightStubFileElementType import me.zhouxi.slint.lang.SlintLanguage import me.zhouxi.slint.stubs.impl.SlintFileStubImpl +import me.zhouxi.slint.stubs.stub.SlintFileStub -object SlintFileElementType : ILightStubFileElementType("SlintFile", SlintLanguage.INSTANCE) { +object SlintFileElementType : ILightStubFileElementType("SlintFile", SlintLanguage.INSTANCE) { override fun getStubVersion(): Int { return 1 } + override fun deserialize(dataStream: StubInputStream, parentStub: StubElement<*>?): SlintFileStub { + return SlintFileStubImpl(null) + } }