From b9a77b4453014b6d1b2cc04a8738561182858b97 Mon Sep 17 00:00:00 2001 From: me Date: Thu, 23 May 2024 19:27:43 +0800 Subject: [PATCH] initial commit --- src/main/grammar/main.bnf | 14 ++++-- .../zhouxi/slint/lang/SlintElementType.java | 2 +- .../lang/{Slint.java => SlintLanguage.java} | 8 +-- .../slint/lang/SlintParserDefinition.java | 10 +++- .../me/zhouxi/slint/lang/SlintTokenType.java | 2 +- .../me/zhouxi/slint/lang/psi/SlintFile.java | 4 +- .../zhouxi/slint/lang/psi/SlintFileType.java | 6 +-- .../psi/{ => impl}/SlintPsiElementImpl.java | 5 +- .../SlintReferencedIdentifierMixinImpl.java | 1 - .../impl/SlintStubBasedPsiNamedElementImpl.kt | 49 +++++++++++++++++++ .../formatter/SlintLineIndentProvider.kt | 4 +- .../zhouxi/slint/lang/SlintElementFactory.kt | 2 +- .../slint/preview/PreviewConfigurationType.kt | 4 +- .../PreviewRunLineMarkerContributor.kt | 4 +- 14 files changed, 88 insertions(+), 27 deletions(-) rename src/main/java/me/zhouxi/slint/lang/{Slint.java => SlintLanguage.java} (61%) rename src/main/java/me/zhouxi/slint/lang/psi/{ => impl}/SlintPsiElementImpl.java (53%) create mode 100644 src/main/java/me/zhouxi/slint/lang/psi/impl/SlintStubBasedPsiNamedElementImpl.kt diff --git a/src/main/grammar/main.bnf b/src/main/grammar/main.bnf index 12dea24..2270d38 100644 --- a/src/main/grammar/main.bnf +++ b/src/main/grammar/main.bnf @@ -2,7 +2,7 @@ generate=[token-case="as-is" element-case="as-is"] parserClass="me.zhouxi.slint.lang.parser.SlintParser" implements="me.zhouxi.slint.lang.psi.SlintPsiElement" - extends="me.zhouxi.slint.lang.psi.SlintPsiElementImpl" + extends="me.zhouxi.slint.lang.psi.impl.SlintPsiElementImpl" elementTypeHolderClass="me.zhouxi.slint.lang.psi.SlintTypes" elementTypeClass="me.zhouxi.slint.lang.SlintElementType" tokenTypeClass="me.zhouxi.slint.lang.SlintTokenType" @@ -133,8 +133,12 @@ ExportModule ::= '*' FromKeyword ModuleLocation ';'{ Component ::= ComponentKeyword ComponentName InheritDeclaration? ComponentBody { pin=1 - implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"] - mixin="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementMixinImpl" + implements=[ + "me.zhouxi.slint.lang.psi.SlintPsiNamedElement" + "com.intellij.psi.StubBasedPsiElement" + ] + stubClass="me.zhouxi.slint.stubs.stub.SlintComponentStub" + mixin="me.zhouxi.slint.lang.psi.impl.SlintStubBasedPsiNamedElementImpl" } //组件定义 //private LegacyComponent ::= (ComponentName|NamedIdentifier ':=' ) ComponentBody @@ -183,7 +187,7 @@ PropertyChanged ::= ChangedKeyword LocalVariable '=>' CodeBlock{ // 回调定义 pure callback abc()->int; callback abc; callback(..);callback()->type; CallbackDeclaration ::= PureKeyword? CallbackKeyword FunctionName CallbackBinding? ';'{ pin=2 - implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"] + implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement""me.zhouxi.slint.stubs.SlintPsiStubElement<>"] mixin="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementMixinImpl" } //回调参数定义 @@ -502,7 +506,7 @@ Named ::= PropertyName | TypeName |ExternalName | InternalName|ComponentName|Fu pin=1 } { - extends("PropertyName|TypeName|ComponentName|FunctionName")=Named + extends("PropertyName|TypeName|ComponentName|FunctionName|InternalName|ExternalName")=Named } LocalVariable ::= GenericIdentifier{ mixin="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementMixinImpl" diff --git a/src/main/java/me/zhouxi/slint/lang/SlintElementType.java b/src/main/java/me/zhouxi/slint/lang/SlintElementType.java index 58f8af9..ab84f59 100644 --- a/src/main/java/me/zhouxi/slint/lang/SlintElementType.java +++ b/src/main/java/me/zhouxi/slint/lang/SlintElementType.java @@ -8,7 +8,7 @@ public final class SlintElementType extends IElementType { public SlintElementType(@NonNls @NotNull String rawKind) { - super(rawKind, Slint.INSTANCE); + super(rawKind, SlintLanguage.INSTANCE); } diff --git a/src/main/java/me/zhouxi/slint/lang/Slint.java b/src/main/java/me/zhouxi/slint/lang/SlintLanguage.java similarity index 61% rename from src/main/java/me/zhouxi/slint/lang/Slint.java rename to src/main/java/me/zhouxi/slint/lang/SlintLanguage.java index e690968..89443f5 100644 --- a/src/main/java/me/zhouxi/slint/lang/Slint.java +++ b/src/main/java/me/zhouxi/slint/lang/SlintLanguage.java @@ -9,13 +9,13 @@ import static com.intellij.openapi.util.IconLoader.getIcon; /** * @author zhouxi 2024/4/30 */ -public class Slint extends Language { +public class SlintLanguage extends Language { - public static final Slint INSTANCE = new Slint(); + public static final SlintLanguage INSTANCE = new SlintLanguage(); - protected Slint() { + protected SlintLanguage() { super("Slint"); } - public static final Icon ICON = getIcon("META-INF/pluginIcon.svg", Slint.class); + public static final Icon ICON = getIcon("META-INF/pluginIcon.svg", SlintLanguage.class); } diff --git a/src/main/java/me/zhouxi/slint/lang/SlintParserDefinition.java b/src/main/java/me/zhouxi/slint/lang/SlintParserDefinition.java index f227f00..bf0b8cf 100644 --- a/src/main/java/me/zhouxi/slint/lang/SlintParserDefinition.java +++ b/src/main/java/me/zhouxi/slint/lang/SlintParserDefinition.java @@ -10,11 +10,14 @@ import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.tree.IFileElementType; +import com.intellij.psi.tree.ILightStubFileElementType; import com.intellij.psi.tree.TokenSet; import me.zhouxi.slint.lang.lexer.SlintLexer; import me.zhouxi.slint.lang.parser.SlintParser; import me.zhouxi.slint.lang.psi.SlintFile; import me.zhouxi.slint.lang.psi.SlintTypes; +import me.zhouxi.slint.stubs.impl.SlintFileStub; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import static me.zhouxi.slint.lang.psi.SlintTypes.*; @@ -38,7 +41,12 @@ public class SlintParserDefinition implements ParserDefinition { return FileType; } - public static final IFileElementType FileType = new IFileElementType("SlintFile",Slint.INSTANCE); + public static final ILightStubFileElementType FileType = new ILightStubFileElementType<>("SlintFile", SlintLanguage.INSTANCE) { + @Override + public @NonNls @NotNull String getExternalId() { + return "slint.FILE"; + } + }; @Override public @NotNull TokenSet getCommentTokens() { diff --git a/src/main/java/me/zhouxi/slint/lang/SlintTokenType.java b/src/main/java/me/zhouxi/slint/lang/SlintTokenType.java index d0254a6..0995593 100644 --- a/src/main/java/me/zhouxi/slint/lang/SlintTokenType.java +++ b/src/main/java/me/zhouxi/slint/lang/SlintTokenType.java @@ -10,7 +10,7 @@ import org.jetbrains.annotations.NotNull; public class SlintTokenType extends IElementType { public SlintTokenType(@NonNls @NotNull String kind) { - super(kind, Slint.INSTANCE); + super(kind, SlintLanguage.INSTANCE); } } diff --git a/src/main/java/me/zhouxi/slint/lang/psi/SlintFile.java b/src/main/java/me/zhouxi/slint/lang/psi/SlintFile.java index 2d52b73..34b3446 100644 --- a/src/main/java/me/zhouxi/slint/lang/psi/SlintFile.java +++ b/src/main/java/me/zhouxi/slint/lang/psi/SlintFile.java @@ -4,7 +4,7 @@ import com.intellij.extapi.psi.PsiFileBase; import com.intellij.openapi.fileTypes.FileType; import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiFile; -import me.zhouxi.slint.lang.Slint; +import me.zhouxi.slint.lang.SlintLanguage; import org.jetbrains.annotations.NotNull; /** @@ -13,7 +13,7 @@ import org.jetbrains.annotations.NotNull; public class SlintFile extends PsiFileBase implements PsiFile { public SlintFile(@NotNull FileViewProvider viewProvider) { - super(viewProvider, Slint.INSTANCE); + super(viewProvider, SlintLanguage.INSTANCE); } @Override diff --git a/src/main/java/me/zhouxi/slint/lang/psi/SlintFileType.java b/src/main/java/me/zhouxi/slint/lang/psi/SlintFileType.java index de2597c..5964eda 100644 --- a/src/main/java/me/zhouxi/slint/lang/psi/SlintFileType.java +++ b/src/main/java/me/zhouxi/slint/lang/psi/SlintFileType.java @@ -3,7 +3,7 @@ package me.zhouxi.slint.lang.psi; import com.intellij.openapi.fileTypes.LanguageFileType; import com.intellij.openapi.util.NlsContexts; import com.intellij.openapi.util.NlsSafe; -import me.zhouxi.slint.lang.Slint; +import me.zhouxi.slint.lang.SlintLanguage; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -17,7 +17,7 @@ public class SlintFileType extends LanguageFileType { public static final SlintFileType INSTANCE = new SlintFileType(); protected SlintFileType() { - super(Slint.INSTANCE); + super(SlintLanguage.INSTANCE); } @Override @@ -37,6 +37,6 @@ public class SlintFileType extends LanguageFileType { @Override public Icon getIcon() { - return Slint.ICON; + return SlintLanguage.ICON; } } diff --git a/src/main/java/me/zhouxi/slint/lang/psi/SlintPsiElementImpl.java b/src/main/java/me/zhouxi/slint/lang/psi/impl/SlintPsiElementImpl.java similarity index 53% rename from src/main/java/me/zhouxi/slint/lang/psi/SlintPsiElementImpl.java rename to src/main/java/me/zhouxi/slint/lang/psi/impl/SlintPsiElementImpl.java index 000fdbc..27eec9a 100644 --- a/src/main/java/me/zhouxi/slint/lang/psi/SlintPsiElementImpl.java +++ b/src/main/java/me/zhouxi/slint/lang/psi/impl/SlintPsiElementImpl.java @@ -1,10 +1,11 @@ -package me.zhouxi.slint.lang.psi; +package me.zhouxi.slint.lang.psi.impl; import com.intellij.extapi.psi.ASTWrapperPsiElement; import com.intellij.lang.ASTNode; +import me.zhouxi.slint.lang.psi.SlintPsiElement; import org.jetbrains.annotations.NotNull; -public class SlintPsiElementImpl extends ASTWrapperPsiElement implements SlintPsiElement { +public abstract class SlintPsiElementImpl extends ASTWrapperPsiElement implements SlintPsiElement { public SlintPsiElementImpl(@NotNull ASTNode node) { super(node); diff --git a/src/main/java/me/zhouxi/slint/lang/psi/impl/SlintReferencedIdentifierMixinImpl.java b/src/main/java/me/zhouxi/slint/lang/psi/impl/SlintReferencedIdentifierMixinImpl.java index 396593c..d6dc2af 100644 --- a/src/main/java/me/zhouxi/slint/lang/psi/impl/SlintReferencedIdentifierMixinImpl.java +++ b/src/main/java/me/zhouxi/slint/lang/psi/impl/SlintReferencedIdentifierMixinImpl.java @@ -3,7 +3,6 @@ package me.zhouxi.slint.lang.psi.impl; import com.intellij.lang.ASTNode; import com.intellij.psi.PsiReference; import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry; -import me.zhouxi.slint.lang.psi.SlintPsiElementImpl; import me.zhouxi.slint.lang.psi.SlintPsiReferencedIdentifier; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/me/zhouxi/slint/lang/psi/impl/SlintStubBasedPsiNamedElementImpl.kt b/src/main/java/me/zhouxi/slint/lang/psi/impl/SlintStubBasedPsiNamedElementImpl.kt new file mode 100644 index 0000000..5aaab20 --- /dev/null +++ b/src/main/java/me/zhouxi/slint/lang/psi/impl/SlintStubBasedPsiNamedElementImpl.kt @@ -0,0 +1,49 @@ +package me.zhouxi.slint.lang.psi.impl + +import com.intellij.extapi.psi.StubBasedPsiElementBase +import com.intellij.lang.ASTNode +import com.intellij.openapi.util.NlsSafe +import com.intellij.psi.PsiElement +import com.intellij.psi.stubs.IStubElementType +import com.intellij.psi.stubs.StubElement +import com.intellij.psi.tree.IElementType +import com.intellij.util.IncorrectOperationException +import me.zhouxi.slint.lang.createIdentifier +import me.zhouxi.slint.lang.psi.SlintNamed +import me.zhouxi.slint.lang.psi.SlintPsiElement +import me.zhouxi.slint.lang.psi.SlintPsiNamedElement +import me.zhouxi.slint.stubs.SlintPsiStub + +/** + * @author zhouxi 2024/5/23 + */ +abstract class SlintStubBasedPsiNamedElementImpl> : + StubBasedPsiElementBase, SlintPsiElement, SlintPsiNamedElement { + + constructor(node: ASTNode) : super(node) + + constructor(stub: T, nodeType: IStubElementType<*, *>) : super(stub, nodeType) + + override fun getNameIdentifier(): PsiElement? { + return findChildByClass(SlintNamed::class.java) + } + + override fun getName(): String? { + return nameIdentifier?.text ?: this.text + } + + override fun canNavigate(): Boolean { + return true + } + + override fun getTextOffset(): Int { + return nameIdentifier?.textOffset ?: super.getTextOffset() + } + + @Throws(IncorrectOperationException::class) + override fun setName(name: @NlsSafe String): PsiElement { + val element = nameIdentifier ?: throw IncorrectOperationException() + element.replace(createIdentifier(project, name)) + return this + } +} diff --git a/src/main/kotlin/me/zhouxi/slint/formatter/SlintLineIndentProvider.kt b/src/main/kotlin/me/zhouxi/slint/formatter/SlintLineIndentProvider.kt index d6e8eb7..4bb78e1 100644 --- a/src/main/kotlin/me/zhouxi/slint/formatter/SlintLineIndentProvider.kt +++ b/src/main/kotlin/me/zhouxi/slint/formatter/SlintLineIndentProvider.kt @@ -5,7 +5,7 @@ import com.intellij.psi.TokenType import com.intellij.psi.impl.source.codeStyle.SemanticEditorPosition.SyntaxElement import com.intellij.psi.impl.source.codeStyle.lineIndent.JavaLikeLangLineIndentProvider import com.intellij.psi.tree.IElementType -import me.zhouxi.slint.lang.Slint +import me.zhouxi.slint.lang.SlintLanguage import me.zhouxi.slint.lang.psi.SlintTypes class SlintLineIndentProvider : JavaLikeLangLineIndentProvider() { @@ -16,7 +16,7 @@ class SlintLineIndentProvider : JavaLikeLangLineIndentProvider() { override fun isSuitableForLanguage(language: Language): Boolean { - return language.isKindOf(Slint.INSTANCE) + return language.isKindOf(SlintLanguage.INSTANCE) } companion object { diff --git a/src/main/kotlin/me/zhouxi/slint/lang/SlintElementFactory.kt b/src/main/kotlin/me/zhouxi/slint/lang/SlintElementFactory.kt index 313278f..88e1df9 100644 --- a/src/main/kotlin/me/zhouxi/slint/lang/SlintElementFactory.kt +++ b/src/main/kotlin/me/zhouxi/slint/lang/SlintElementFactory.kt @@ -12,7 +12,7 @@ import me.zhouxi.slint.lang.psi.SlintFile fun createIdentifier(project: Project?, text: String): PsiElement { val factory = PsiFileFactory.getInstance(project) - val file = factory.createFileFromText("dummy.slint", Slint.INSTANCE, "component $text{}") as SlintFile + val file = factory.createFileFromText("dummy.slint", SlintLanguage.INSTANCE, "component $text{}") as SlintFile return file.findChildByClass(SlintComponent::class.java)!!.componentName!!.identifier } diff --git a/src/main/kotlin/me/zhouxi/slint/preview/PreviewConfigurationType.kt b/src/main/kotlin/me/zhouxi/slint/preview/PreviewConfigurationType.kt index a8d22a0..0586569 100644 --- a/src/main/kotlin/me/zhouxi/slint/preview/PreviewConfigurationType.kt +++ b/src/main/kotlin/me/zhouxi/slint/preview/PreviewConfigurationType.kt @@ -2,7 +2,7 @@ package me.zhouxi.slint.preview import com.intellij.execution.configurations.ConfigurationTypeBase import com.intellij.openapi.util.NotNullLazyValue -import me.zhouxi.slint.lang.Slint +import me.zhouxi.slint.lang.SlintLanguage /** * @author zhouxi 2024/5/16 @@ -11,7 +11,7 @@ object PreviewConfigurationType : ConfigurationTypeBase( "SlintViewerConfiguration", "Slint viewer", "Slint component preview", - NotNullLazyValue.createValue { Slint.ICON } + NotNullLazyValue.createValue { SlintLanguage.ICON } ) { init { addFactory(PreviewConfigurationFactory(this)) diff --git a/src/main/kotlin/me/zhouxi/slint/preview/PreviewRunLineMarkerContributor.kt b/src/main/kotlin/me/zhouxi/slint/preview/PreviewRunLineMarkerContributor.kt index f7f863b..d3b5f5e 100644 --- a/src/main/kotlin/me/zhouxi/slint/preview/PreviewRunLineMarkerContributor.kt +++ b/src/main/kotlin/me/zhouxi/slint/preview/PreviewRunLineMarkerContributor.kt @@ -3,7 +3,7 @@ package me.zhouxi.slint.preview import com.intellij.execution.lineMarker.ExecutorAction import com.intellij.execution.lineMarker.RunLineMarkerContributor import com.intellij.psi.PsiElement -import me.zhouxi.slint.lang.Slint +import me.zhouxi.slint.lang.SlintLanguage import me.zhouxi.slint.lang.psi.SlintComponentName /** @@ -13,7 +13,7 @@ class PreviewRunLineMarkerContributor : RunLineMarkerContributor() { override fun getInfo(element: PsiElement): Info? { if (element.parent is SlintComponentName) { return Info( - Slint.ICON, null, + SlintLanguage.ICON, null, *ExecutorAction.getActions(1) ) }