fix: 语法问题

This commit is contained in:
me
2025-08-08 15:49:35 +08:00
parent e0c006cb94
commit 578f8d4661
28 changed files with 156 additions and 222 deletions

View File

@@ -36,9 +36,9 @@ repositories {
} }
intellij { intellij {
version.set("IU-2024.1") version.set("IU-241-EAP-SNAPSHOT")
sandboxDir.set("idea-sandbox") sandboxDir.set("idea-sandbox")
plugins.set(listOf("java")) plugins.set(listOf("java","Git4Idea"))
} }
dependencies { dependencies {
} }

View File

@@ -12,9 +12,6 @@
psiPackage="me.zhouxi.slint.lang.psi" psiPackage="me.zhouxi.slint.lang.psi"
psiImplPackage="me.zhouxi.slint.lang.psi.impl" psiImplPackage="me.zhouxi.slint.lang.psi.impl"
extends(".*Expression")=Expression extends(".*Expression")=Expression
implements(".*Keyword")=["me.zhouxi.slint.lang.psi.SlintPsiKeyword"]
extends(".*Keyword")="me.zhouxi.slint.lang.psi.SlintPsiKeyword.Impl"
elementTypeFactory(".*Keyword")="me.zhouxi.slint.lang.psi.SlintPsiKeyword.type"
tokens=[ tokens=[
Comma = "," Comma = ","
FatArrow = "=>" FatArrow = "=>"
@@ -70,20 +67,20 @@ private recoverTopElement ::= !('component' | 'struct' | 'enum' | 'global'| 'exp
private DocumentElement ::= Import | Struct | Enum | GlobalSingleton | Component | Export { private DocumentElement ::= Import | Struct | Enum | GlobalSingleton | Component | Export {
recoverWhile=recoverTopElement recoverWhile=recoverTopElement
} }
GlobalSingleton ::= ExportKeyword? GlobalKeyword Identifier '{' ComponentElement* '}' { GlobalSingleton ::= 'export'? 'global' Identifier '{' ComponentElement* '}' {
pin=2 pin=2
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"] implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
mixin="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl" mixin="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl"
} }
//import 定义 //import 定义
Import ::= ImportKeyword (ImportElement|ModuleRef)';'{ Import ::= 'import' (ImportElement|ModuleRef)';'{
pin=1 pin=1
elementTypeFactory="me.zhouxi.slint.lang.psi.stubs.types.SlintStubTypes.slintImport" elementTypeFactory="me.zhouxi.slint.lang.psi.stubs.types.SlintStubTypes.slintImport"
stubClass="me.zhouxi.slint.lang.psi.stubs.stub.SlintImportStub" stubClass="me.zhouxi.slint.lang.psi.stubs.stub.SlintImportStub"
extends="me.zhouxi.slint.lang.psi.impl.SlintStubBasedPsiElementImpl<?>" extends="me.zhouxi.slint.lang.psi.impl.SlintStubBasedPsiElementImpl<?>"
} }
ImportElement ::= '{' ImportSpecifier (',' ImportSpecifier)* '}' FromKeyword ModuleRef{ ImportElement ::= '{' ImportSpecifier (',' ImportSpecifier)* '}' 'from' ModuleRef{
pin=1 pin=1
} }
@@ -96,28 +93,28 @@ ImportSpecifier ::= ComponentRef ImportAlias?{
} }
private AliasNameRecover::=!(','|'}'|';') private AliasNameRecover::=!(','|'}'|';')
ImportAlias ::= AsKeyword Identifier { ImportAlias ::= 'as' Identifier {
pin=1 pin=1
recoverWhile=AliasNameRecover recoverWhile=AliasNameRecover
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"] implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
extends="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl" extends="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl"
} }
//Struct 定义 //Struct 定义
Struct ::= ExportKeyword? StructKeyword Identifier (':=')? StructBody { Struct ::= 'export'? 'struct' Identifier (':=')? StructBody {
pin=2 pin=2
} }
private StructBody ::= '{' FieldDeclarations? '}'{ private StructBody ::= '{' FieldDeclarations? '}'{
pin=1 pin=1
} }
//EnumDeclaration //EnumDeclaration
Enum ::= ExportKeyword? EnumKeyword Identifier '{' (Identifier (','Identifier)*','? )? '}'{ Enum ::= 'export'? 'enum' Identifier '{' [Identifier (','Identifier)*','? ] '}'{
pin=2 pin=2
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"] implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
extends="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl" extends="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl"
} }
//--------------ExportsList ------------------------------------- //--------------ExportsList -------------------------------------
//ExportsList //ExportsList
Export ::= ExportKeyword (ExportType | ExportModule) { Export ::= 'export' (ExportType | ExportModule) {
pin=1 pin=1
} }
@@ -129,15 +126,15 @@ ExportSpecifier::= ComponentRef ExportAlias?{
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"] implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
extends="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl" extends="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl"
} }
ExportAlias ::= AsKeyword Identifier{ ExportAlias ::= 'as' Identifier{
pin=1 pin=1
} }
ExportModule ::= '*' FromKeyword ModuleRef ';'{ ExportModule ::= '*' 'from' ModuleRef ';'{
pin=1 pin=1
} }
Component ::= ExportKeyword? ComponentKeyword Identifier InheritDeclaration? '{' ComponentElement* '}' { Component ::= ComponentModifier '{' ComponentElement* '}' {
pin=2 pin=1
implements=[ implements=[
"me.zhouxi.slint.lang.psi.SlintPsiNamedElement" "me.zhouxi.slint.lang.psi.SlintPsiNamedElement"
] ]
@@ -145,18 +142,21 @@ Component ::= ExportKeyword? ComponentKeyword Identifier InheritDeclaration? '{'
stubClass="me.zhouxi.slint.lang.psi.stubs.stub.SlintComponentStub" stubClass="me.zhouxi.slint.lang.psi.stubs.stub.SlintComponentStub"
extends="me.zhouxi.slint.lang.psi.impl.SlintStubBasedPsiNamedElementImpl<?>" extends="me.zhouxi.slint.lang.psi.impl.SlintStubBasedPsiNamedElementImpl<?>"
} }
private ComponentModifier::= 'export'? 'component' Identifier InheritDeclaration?{
pin=2
recoverWhile=recoverInherit
}
//组件定义 //组件定义
//private LegacyComponent ::= (ComponentName|NamedIdentifier ':=' ) ComponentBody InheritDeclaration ::= 'inherits' ComponentRef {
InheritDeclaration ::= InheritsKeyword ComponentRef {
pin=1 pin=1
recoverWhile=recoverInherit recoverWhile=recoverInherit
} }
private recoverInherit::=!('{') private recoverInherit::=!('{')
//组件元素定义 //组件元素定义
private ComponentElement ::=ChildrenPlaceholder| Property | Callback private ComponentElement ::= ChildrenPlaceholder| PropertyDeclaration | CallbackDeclaration
| Function | PropertyAnimation | CallbackConnection | Transitions | Function | PropertyAnimation | CallbackConnection | Transitions
| PropertyChanged | PropertyChanged | States | TwoWayBinding | ConditionalElement
| States | TwoWayBinding | ConditionalElement
| RepetitionElement | SubComponent | PropertyBinding { | RepetitionElement | SubComponent | PropertyBinding {
recoverWhile=recoverWhileForComponentBody recoverWhile=recoverWhileForComponentBody
} }
@@ -167,8 +167,8 @@ ChildrenPlaceholder ::= '@' 'children'{
} }
//--------------------------------PropertyDeclaration Start---------------------------------------------------- //--------------------------------PropertyDeclaration Start----------------------------------------------------
// 属性定义 in property <type> name: value / in property <type> name <=> value // 属性定义 in property <type> name: value / in property <type> name <=> value
Property ::= PropertyModifier? PropertyKeyword ('<' Type '>')? Identifier (PropertyValue|PropertyTwoWayBindingValue|';'){ PropertyDeclaration ::= PropertyModifier? 'property' ('<' Type '>')? Identifier PropertyDeclarationValue{
pin=2 pin=4
implements=[ implements=[
"me.zhouxi.slint.lang.psi.SlintPsiNamedElement" "me.zhouxi.slint.lang.psi.SlintPsiNamedElement"
] ]
@@ -176,33 +176,34 @@ Property ::= PropertyModifier? PropertyKeyword ('<' Type '>')? Identifier (Prope
stubClass="me.zhouxi.slint.lang.psi.stubs.stub.SlintPropertyStub" stubClass="me.zhouxi.slint.lang.psi.stubs.stub.SlintPropertyStub"
extends="me.zhouxi.slint.lang.psi.impl.SlintStubBasedPsiNamedElementImpl<?>" extends="me.zhouxi.slint.lang.psi.impl.SlintStubBasedPsiNamedElementImpl<?>"
} }
PropertyModifier ::= InKeyword|OutKeyword|InOutKeyword|PrivateKeyword //修饰符
private PropertyValue::= ':' BindingStatement { PropertyModifier ::= 'in'|'out'|'in-out'|'private'
pin=1
} //属性定义的ValueBinding
private PropertyTwoWayBindingValue ::= '<=>' QualifiedPropertyRef ';' { PropertyDeclarationValue::=(':' BindingExpressionStatement)| ('<=>' Expression ';') | ';'
pin=1
} //绑定类型表达式
BindingExpressionStatement::= '{' '}' | Expression ';' | '{' Expression '}' | ObjectCreationExpression ';'
//--------------------------------PropertyChanged Start---------------------------------------------------- //--------------------------------PropertyChanged Start----------------------------------------------------
PropertyChanged ::= ChangedKeyword LocalVariable '=>' CodeBlock{ PropertyChanged ::= 'changed' LocalVariable '=>' CodeBlock{
pin=1 pin=1
} }
//--------------------------------CallbackDeclaration Start---------------------------------------------------- //--------------------------------CallbackDeclaration Start----------------------------------------------------
// 回调定义 pure callback abc()->int; callback abc; callback(..);callback()->type; // 回调定义 pure callback abc()->int; callback abc; callback(..);callback()->type;
Callback ::= PureKeyword? CallbackKeyword Identifier CallbackBinding? ';'{ CallbackDeclaration ::= 'pure'? 'callback' Identifier CallbackArgument? CallbackBinding? ';'{
pin=2 pin=2
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"] implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
extends="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl" extends="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl"
} }
//回调参数定义 //回调参数定义
CallbackBinding::= CallbackArgument | ('<=>'QualifiedPropertyRef) CallbackBinding::= CallbackArgument | ('<=>'QualifiedPropertyRef)
//入参定义 //入参定义
CallbackArgument ::= '(' (Type (','Type)* ','? )? ')' ReturnType?{ CallbackArgument ::= '(' (Type (','Type)* ','? )? ')' ('->' Type)?{
pin=1
}
private ReturnType ::= '->' (QualifiedTypeRef|ArrayType){
pin=1 pin=1
} }
//--------------------------------TwoWayBindingDeclaration Start---------------------------------------------------- //--------------------------------TwoWayBindingDeclaration Start----------------------------------------------------
//组件双向绑定 //组件双向绑定
TwoWayBinding ::= PropertyRef '<=>' QualifiedPropertyRef ';' { TwoWayBinding ::= PropertyRef '<=>' QualifiedPropertyRef ';' {
@@ -211,12 +212,12 @@ TwoWayBinding ::= PropertyRef '<=>' QualifiedPropertyRef ';' {
//--------------------------------FunctionDeclaration Start---------------------------------------------------- //--------------------------------FunctionDeclaration Start----------------------------------------------------
//函数定义 protected? pure? function f() //函数定义 protected? pure? function f()
Function ::= FunctionModifiers? FunctionKeyword Identifier FunctionArguments ReturnType? CodeBlock{ Function ::= FunctionModifiers? 'function' Identifier FunctionArguments ReturnType? CodeBlock{
pin=2 pin=3
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"] implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
extends="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl" extends="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl"
} }
private FunctionModifiers ::= ((PublicKeyword | ProtectedKeyword) PureKeyword?) | (PureKeyword (PublicKeyword | ProtectedKeyword)?) private FunctionModifiers ::= (('public' | 'protected') 'pure'?) | ('pure' ('public' | 'protected')?)
private FunctionArguments ::= '(' FieldDeclarations* ')'{ private FunctionArguments ::= '(' FieldDeclarations* ')'{
pin=1 pin=1
@@ -230,10 +231,10 @@ CallbackConnection ::= FunctionRef CallbackConnectionArguments? '=>' CodeBlock '
private CallbackConnectionArguments ::= '(' (LocalVariable (',' LocalVariable)* ','?)? ')' private CallbackConnectionArguments ::= '(' (LocalVariable (',' LocalVariable)* ','?)? ')'
//--------------------------------ConditionalElementDeclaration Start--------------------------------------------------- //--------------------------------ConditionalElementDeclaration Start---------------------------------------------------
ConditionalElement ::= IfKeyword Expression ':' SubComponent{ ConditionalElement ::= 'if' Expression ':' SubComponent{
pin=1 pin=1
} }
RepetitionElement ::= ForKeyword RepetitionVariable InKeyword Expression ':' SubComponent { RepetitionElement ::= 'for' RepetitionVariable 'in' Expression ':' SubComponent {
pin=1 pin=1
} }
private RepetitionVariable ::= LocalVariable RepetitionIndex?{ private RepetitionVariable ::= LocalVariable RepetitionIndex?{
@@ -252,17 +253,17 @@ SubComponent ::= (Identifier ':=')? ComponentRef '{' ComponentElement* '}'{
//--------------------------------TransitionsDeclaration Start--------------------------------------------------- //--------------------------------TransitionsDeclaration Start---------------------------------------------------
//过渡绑定 //过渡绑定
Transitions ::= TransitionsKeyword '[' Transition* ']'{ Transitions ::= 'transitions' '[' Transition* ']'{
pin=1 pin=1
} }
// //
Transition ::= (InKeyword|OutKeyword) LocalVariable ':' '{' PropertyAnimation* '}'{ Transition ::= ('in'|'out') LocalVariable ':' '{' PropertyAnimation* '}'{
pin=1 pin=1
recoverWhile=recoverForRBracket recoverWhile=recoverForRBracket
} }
//--------------------------------TransitionsDeclaration End--------------------------------------------------- //--------------------------------TransitionsDeclaration End---------------------------------------------------
// in | out name : { } // in | out name : { }
States ::= StatesKeyword '[' State* ']'{ States ::= 'states' '[' State* ']'{
pin=1 pin=1
} }
// identifier [when] : { ... } // identifier [when] : { ... }
@@ -273,17 +274,20 @@ State ::= LocalVariable StateCondition? ':' '{' StateItem* '}' {
recoverWhile=recoverForRBracket recoverWhile=recoverForRBracket
} }
private recoverForRBracket::=!(']'|'}'|';'|Identifier) private recoverForRBracket::=!(']'|'}'|';'|Identifier)
StateCondition ::= WhenKeyword Expression { StateCondition ::= 'when' Expression {
pin=1 pin=1
} }
//状态可以由transition propertyBinding 和 animationBinding组成 //状态可以由transition propertyBinding 和 animationBinding组成
private StateItem ::= QualifiedNamePropertyBinding | StateTransition private StateItem ::= QualifiedNamePropertyBinding | StateTransition
StateTransition ::= (InKeyword|OutKeyword) ':' '{' PropertyAnimation* '}'{ StateTransition ::= ('in'|'out') ':' '{' PropertyAnimation* '}'{
pin=1 pin=1
} }
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
//类型定义 //类型定义
Type ::= QualifiedTypeRef | UnnamedType | ArrayType Type ::= TypeRef | UnnamedType | ArrayType
TypeRef::=QualifiedName{
extends=Referred
}
ArrayType ::= '[' Type ']' ArrayType ::= '[' Type ']'
UnnamedType ::= '{' FieldDeclarations* '}' UnnamedType ::= '{' FieldDeclarations* '}'
private FieldDeclarations ::= FieldDeclaration (',' FieldDeclaration)* ','? private FieldDeclarations ::= FieldDeclaration (',' FieldDeclaration)* ','?
@@ -303,23 +307,23 @@ ExpressionStatement ::= Expression (';'+ | &'}') {
//private recoverWhileStatement::=!(GenericIdentifier|';'|'}') //private recoverWhileStatement::=!(GenericIdentifier|';'|'}')
ReturnStatement ::= ReturnKeyword (Expression)?{ ReturnStatement ::= 'return' (Expression)?{
pin=1 pin=1
} }
private IfElseStatement ::= IfStatement (ElseIfStatement)* ElseStatement?{ private IfElseStatement ::= IfStatement (ElseIfStatement)* ElseStatement?{
pin=1 pin=1
} }
IfStatement ::= IfKeyword Expression CodeBlock { IfStatement ::= 'if' Expression CodeBlock {
pin=1 pin=1
} }
ElseIfStatement ::= ElseKeyword IfKeyword Expression CodeBlock{ ElseIfStatement ::= 'else' 'if' Expression CodeBlock{
pin=2 pin=2
} }
ElseStatement ::= ElseKeyword CodeBlock { ElseStatement ::= 'else' CodeBlock {
pin=1 pin=1
} }
//动画定义 //动画定义
PropertyAnimation ::= AnimateKeyword ('*'| (QualifiedPropertyRef (',' QualifiedPropertyRef)*)) '{' QualifiedNamePropertyBinding*'}'{ PropertyAnimation ::= 'animate' ('*'| (QualifiedPropertyRef (',' QualifiedPropertyRef)*)) '{' QualifiedNamePropertyBinding*'}'{
pin=1 pin=1
} }
//组件属性绑定 name: xxx ; name : {}; name : {} //组件属性绑定 name: xxx ; name : {}; name : {}
@@ -480,37 +484,7 @@ private ObjectPropertyBinding ::= Identifier ':' Expression{
recoverWhile=recover recoverWhile=recover
} }
private recover::=!(';'|'}'|',') private recover::=!(';'|'}'|',')
//-------------------------------For Keyword highlighting------------------------------------
ComponentKeyword ::= 'component'
StructKeyword ::='struct'
EnumKeyword::='enum'
GlobalKeyword::='global'
ExportKeyword::='export'
ImportKeyword::='import'
AsKeyword::='as'
FromKeyword::='from'
InheritsKeyword::='inherits'
PropertyKeyword::='property'
CallbackKeyword::='callback'
StatesKeyword::='states'
TransitionsKeyword::='transitions'
PureKeyword::='pure'
FunctionKeyword::='function'
PublicKeyword::='public'
ProtectedKeyword::='protected'
ForKeyword::='for'
IfKeyword::='if'
ChangedKeyword::='changed'
InKeyword::='in'
WhenKeyword::='when'
ElseKeyword::='else'
AnimateKeyword::='animate'
OutKeyword::='out'
InOutKeyword::='in-out'
PrivateKeyword::='private'
ReturnKeyword::='return'
//---------NamedIdentifier ,简化PsiTree-----------------------------------
//noinspection BnfUnusedRule 用于标记命名节点对应的identifier
LocalVariable ::= Identifier{ LocalVariable ::= Identifier{
extends="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl" extends="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl"
implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"] implements=["me.zhouxi.slint.lang.psi.SlintPsiNamedElement"]
@@ -528,13 +502,9 @@ QualifiedPropertyRef ::= PropertyRef ('.' PropertyRef)*{
PropertyRef ::= Identifier{ PropertyRef ::= Identifier{
extends=Referred extends=Referred
} }
QualifiedTypeRef::= TypeRef ('.' TypeRef)*{
extends=TypeRef
}
TypeRef::=Identifier{ QualifiedName::=Identifier('.' Identifier)*
extends=Referred
}
FunctionRef::=Identifier{ FunctionRef::=Identifier{
extends=Referred extends=Referred
} }

View File

@@ -1,37 +0,0 @@
package me.zhouxi.slint.lang.psi;
import com.intellij.lang.ASTNode;
import me.zhouxi.slint.lang.SlintElementType;
import me.zhouxi.slint.lang.psi.impl.SlintPsiElementImpl;
import org.jetbrains.annotations.NotNull;
public interface SlintPsiKeyword extends SlintPsiElement {
abstract class Impl extends SlintPsiElementImpl implements SlintPsiKeyword {
public Impl(@NotNull ASTNode node) {
super(node);
}
@Override
public String toString() {
return "SlintKeyword:" + getText();
}
}
static ElementType type(String debugName) {
return ElementType.TYPE;
}
class ElementType extends SlintElementType {
public static final ElementType TYPE = new ElementType("SlintKeyword");
private ElementType(@NotNull String debugName) {
super(debugName);
}
}
}

View File

@@ -19,11 +19,12 @@ class SlintPairedBraceMatcher : PairedBraceMatcher {
return 0 return 0
} }
} companion object {
val Pair: Array<BracePair> = arrayOf(
val Pair: Array<BracePair> = arrayOf(
BracePair(SlintTypes.LBrace, SlintTypes.RBrace, true), BracePair(SlintTypes.LBrace, SlintTypes.RBrace, true),
BracePair(SlintTypes.LParent, SlintTypes.RParent, true), BracePair(SlintTypes.LParent, SlintTypes.RParent, true),
BracePair(SlintTypes.LBracket, SlintTypes.RBracket, true), BracePair(SlintTypes.LBracket, SlintTypes.RBracket, true),
BracePair(SlintTypes.LAngle, SlintTypes.RAngle, true) BracePair(SlintTypes.LAngle, SlintTypes.RAngle, true)
) )
}
}

View File

@@ -18,10 +18,11 @@ class SlintCompletionContributor : CompletionContributor() {
extend(InheritsCompletionProvider) extend(InheritsCompletionProvider)
extend(ExportElementProvider) extend(ExportElementProvider)
extend(SubComponentNameProvider) extend(SubComponentNameProvider)
extend(PropertyDeclarationProvider)
} }
private fun extend( private fun extend(
provider: AbstractSlintCompletionProvider<CompletionParameters>, provider: AbstractSlintCompletionProvider,
type: CompletionType = CompletionType.BASIC, type: CompletionType = CompletionType.BASIC,
) { ) {
extend(type, provider.pattern(), provider) extend(type, provider.pattern(), provider)

View File

@@ -8,7 +8,7 @@ import com.intellij.psi.PsiElement
/** /**
* @author zhouxi 2024/5/29 * @author zhouxi 2024/5/29
*/ */
abstract class AbstractSlintCompletionProvider<V : CompletionParameters> : CompletionProvider<V>() { abstract class AbstractSlintCompletionProvider : CompletionProvider<CompletionParameters>() {
abstract fun pattern(): ElementPattern<out PsiElement> abstract fun pattern(): ElementPattern<out PsiElement>
} }

View File

@@ -9,10 +9,11 @@ import com.intellij.patterns.PlatformPatterns.psiElement
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.util.ProcessingContext import com.intellij.util.ProcessingContext
import me.zhouxi.slint.lang.psi.SlintTypes.Component import me.zhouxi.slint.lang.psi.SlintTypes.Component
/** /**
* @author zhouxi 2024/5/29 * @author zhouxi 2024/5/29
*/ */
object AtChildrenCompletionProvider : AbstractSlintCompletionProvider<CompletionParameters>() { object AtChildrenCompletionProvider : AbstractSlintCompletionProvider() {
override fun pattern(): ElementPattern<out PsiElement> { override fun pattern(): ElementPattern<out PsiElement> {
return psiElement() return psiElement()
.afterLeaf(psiElement().withText("@")) .afterLeaf(psiElement().withText("@"))

View File

@@ -10,7 +10,7 @@ import com.intellij.util.ProcessingContext
import me.zhouxi.slint.lang.psi.SlintPsiUtils.InternalTypes import me.zhouxi.slint.lang.psi.SlintPsiUtils.InternalTypes
import me.zhouxi.slint.lang.psi.SlintTypes.Type import me.zhouxi.slint.lang.psi.SlintTypes.Type
object BasicTypeProvider : AbstractSlintCompletionProvider<CompletionParameters>() { object BasicTypeProvider : AbstractSlintCompletionProvider() {
override fun addCompletions( override fun addCompletions(
parameters: CompletionParameters, parameters: CompletionParameters,
context: ProcessingContext, context: ProcessingContext,

View File

@@ -9,7 +9,7 @@ import com.intellij.psi.PsiElement
import com.intellij.util.ProcessingContext import com.intellij.util.ProcessingContext
import me.zhouxi.slint.lang.psi.SlintTypes.Component import me.zhouxi.slint.lang.psi.SlintTypes.Component
object ComponentElementKeywordProvider : AbstractSlintCompletionProvider<CompletionParameters>() { object ComponentElementKeywordProvider : AbstractSlintCompletionProvider() {
override fun addCompletions( override fun addCompletions(
parameters: CompletionParameters, parameters: CompletionParameters,
context: ProcessingContext, context: ProcessingContext,

View File

@@ -14,7 +14,7 @@ import me.zhouxi.slint.lang.psi.SlintTypes.InheritDeclaration
import me.zhouxi.slint.lang.psi.extension.relativePathOf import me.zhouxi.slint.lang.psi.extension.relativePathOf
import me.zhouxi.slint.lang.psi.stubs.index.searchComponent import me.zhouxi.slint.lang.psi.stubs.index.searchComponent
object ComponentNameProvider : AbstractSlintCompletionProvider<CompletionParameters>() { object ComponentNameProvider : AbstractSlintCompletionProvider() {
override fun addCompletions( override fun addCompletions(
parameters: CompletionParameters, parameters: CompletionParameters,
context: ProcessingContext, context: ProcessingContext,

View File

@@ -20,7 +20,7 @@ import me.zhouxi.slint.lang.psi.stubs.types.SlintFileElementType
/** /**
* @author zhouxi 2024/6/6 * @author zhouxi 2024/6/6
*/ */
object ExportElementProvider : AbstractSlintCompletionProvider<CompletionParameters>() { object ExportElementProvider : AbstractSlintCompletionProvider() {
override fun pattern(): ElementPattern<out PsiElement> { override fun pattern(): ElementPattern<out PsiElement> {

View File

@@ -12,7 +12,7 @@ import me.zhouxi.slint.lang.psi.SlintTypes
/** /**
* @author zhouxi 2024/5/29 * @author zhouxi 2024/5/29
*/ */
object InheritsCompletionProvider : AbstractSlintCompletionProvider<CompletionParameters>() { object InheritsCompletionProvider : AbstractSlintCompletionProvider() {
override fun pattern(): ElementPattern<out PsiElement> { override fun pattern(): ElementPattern<out PsiElement> {
return PlatformPatterns.psiElement() return PlatformPatterns.psiElement()
.afterLeaf(PlatformPatterns.psiElement().withParent(PlatformPatterns.psiElement(SlintTypes.IDENTIFIER))) .afterLeaf(PlatformPatterns.psiElement().withParent(PlatformPatterns.psiElement(SlintTypes.IDENTIFIER)))

View File

@@ -19,7 +19,7 @@ import me.zhouxi.slint.lang.psi.extension.inheritsProperties
import me.zhouxi.slint.lang.psi.extension.resolve import me.zhouxi.slint.lang.psi.extension.resolve
import me.zhouxi.slint.lang.psi.extension.toLookupElement import me.zhouxi.slint.lang.psi.extension.toLookupElement
object PropertyBindingProvider : AbstractSlintCompletionProvider<CompletionParameters>() { object PropertyBindingProvider : AbstractSlintCompletionProvider() {
override fun addCompletions( override fun addCompletions(
parameters: CompletionParameters, parameters: CompletionParameters,
context: ProcessingContext, context: ProcessingContext,

View File

@@ -0,0 +1,65 @@
package me.zhouxi.slint.completion.provider
import com.intellij.codeInsight.completion.CompletionParameters
import com.intellij.codeInsight.completion.CompletionResultSet
import com.intellij.codeInsight.completion.InsertHandler
import com.intellij.codeInsight.completion.InsertionContext
import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.LookupElementBuilder
import com.intellij.codeInsight.lookup.LookupElementBuilder.*
import com.intellij.codeInsight.template.Template
import com.intellij.codeInsight.template.TemplateEditingAdapter
import com.intellij.codeInsight.template.TemplateManager
import com.intellij.codeInsight.template.impl.ConstantNode
import com.intellij.patterns.ElementPattern
import com.intellij.patterns.PlatformPatterns.psiElement
import com.intellij.patterns.StandardPatterns.or
import com.intellij.psi.PsiElement
import com.intellij.util.ProcessingContext
import me.zhouxi.slint.lang.psi.SlintTypes.Component
import me.zhouxi.slint.lang.psi.SlintTypes.SubComponent
/**
* @author zhouxi 2024/6/6
*/
object PropertyDeclarationProvider : AbstractSlintCompletionProvider() {
override fun pattern(): ElementPattern<out PsiElement> {
return psiElement().withParent(or(psiElement(Component), psiElement(SubComponent)))
}
override fun addCompletions(
parameters: CompletionParameters,
context: ProcessingContext,
result: CompletionResultSet
) {
result.addAllElements(lookup)
}
val lookup = arrayOf(
create("property"),
create("in property"),
create("out property"),
create("in-out property")
).flatMap { arrayListOf(it.withInsertHandler(InternalInsertHandler())) }
.map { it.withBoldness(true) }
class InternalInsertHandler : InsertHandler<LookupElement> {
override fun handleInsert(context: InsertionContext, item: LookupElement) {
val manager = TemplateManager.getInstance(context.project)
val template = manager.createTemplate("", "", "<\$Type$> \$Name$;").apply {
isToReformat = true
addVariable("Type", ConstantNode(""), true)
addVariable("Name", ConstantNode(""), true)
}
manager.startTemplate(context.editor, template, object : TemplateEditingAdapter() {
override fun templateFinished(template: Template, brokenOff: Boolean) {
context.editor.caretModel.moveToOffset(context.tailOffset - 2);
}
})
}
}
}

View File

@@ -30,7 +30,7 @@ import me.zhouxi.slint.lang.psi.extension.relativePathOf
import me.zhouxi.slint.lang.psi.stubs.index.searchComponent import me.zhouxi.slint.lang.psi.stubs.index.searchComponent
object SubComponentNameProvider object SubComponentNameProvider
: AbstractSlintCompletionProvider<CompletionParameters>() { : AbstractSlintCompletionProvider() {
override fun addCompletions( override fun addCompletions(
parameters: CompletionParameters, parameters: CompletionParameters,
context: ProcessingContext, context: ProcessingContext,

View File

@@ -17,7 +17,7 @@ import com.intellij.util.ProcessingContext
import me.zhouxi.slint.lang.psi.SlintTypes.Component import me.zhouxi.slint.lang.psi.SlintTypes.Component
import me.zhouxi.slint.lang.psi.stubs.types.SlintFileElementType import me.zhouxi.slint.lang.psi.stubs.types.SlintFileElementType
object TopElementProvider : AbstractSlintCompletionProvider<CompletionParameters>() { object TopElementProvider : AbstractSlintCompletionProvider() {
override fun addCompletions( override fun addCompletions(
parameters: CompletionParameters, parameters: CompletionParameters,
context: ProcessingContext, context: ProcessingContext,

View File

@@ -5,13 +5,10 @@ import com.intellij.lang.ASTNode
import com.intellij.psi.TokenType import com.intellij.psi.TokenType
import com.intellij.psi.formatter.common.AbstractBlock import com.intellij.psi.formatter.common.AbstractBlock
import com.intellij.psi.tree.TokenSet import com.intellij.psi.tree.TokenSet
import me.zhouxi.slint.lang.psi.SlintPsiKeyword
import me.zhouxi.slint.lang.psi.SlintTypes
import me.zhouxi.slint.lang.psi.SlintTypes.* import me.zhouxi.slint.lang.psi.SlintTypes.*
import me.zhouxi.slint.lang.psi.stubs.types.SlintFileElementType import me.zhouxi.slint.lang.psi.stubs.types.SlintFileElementType
import me.zhouxi.slint.lang.psi.utils.braces import me.zhouxi.slint.lang.psi.utils.braces
import me.zhouxi.slint.lang.psi.utils.expressions import me.zhouxi.slint.lang.psi.utils.expressions
import me.zhouxi.slint.lang.psi.utils.keywords
/** /**
* @author zhouxi 2024/5/28 * @author zhouxi 2024/5/28
@@ -85,8 +82,7 @@ class FormattingBlock(
FunctionRef, FunctionRef,
TypeRef, TypeRef,
LocalVariable, LocalVariable,
PropertyModifier, PropertyModifier
SlintPsiKeyword.ElementType.TYPE
) )
private val syntheticParentTokens = TokenSet.create( private val syntheticParentTokens = TokenSet.create(

View File

@@ -7,10 +7,8 @@ import com.intellij.psi.PsiFile
import com.intellij.psi.codeStyle.CodeStyleSettings import com.intellij.psi.codeStyle.CodeStyleSettings
import com.intellij.psi.tree.TokenSet import com.intellij.psi.tree.TokenSet
import me.zhouxi.slint.lang.SlintLanguage import me.zhouxi.slint.lang.SlintLanguage
import me.zhouxi.slint.lang.psi.SlintTypes
import me.zhouxi.slint.lang.psi.SlintTypes.* import me.zhouxi.slint.lang.psi.SlintTypes.*
import me.zhouxi.slint.lang.psi.stubs.types.SlintFileElementType import me.zhouxi.slint.lang.psi.stubs.types.SlintFileElementType
import me.zhouxi.slint.lang.psi.utils.keywords
/** /**
* @author zhouxi 2024/5/7 * @author zhouxi 2024/5/7
@@ -54,8 +52,6 @@ class SlintFormatterModelBuilder : FormattingModelBuilder {
.spaces(1) .spaces(1)
.before(CodeBlock) .before(CodeBlock)
.spacing(1, 1, 0, true, 2) .spacing(1, 1, 0, true, 2)
.around(keywords)
.spaces(1)
.after(RAngle) .after(RAngle)
.spaces(1) .spaces(1)
.afterInside(TokenSet.ANY, SlintFileElementType) .afterInside(TokenSet.ANY, SlintFileElementType)

View File

@@ -6,7 +6,6 @@ import com.intellij.lang.annotation.HighlightSeverity
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors import com.intellij.openapi.editor.DefaultLanguageHighlighterColors
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import me.zhouxi.slint.lang.psi.* import me.zhouxi.slint.lang.psi.*
import me.zhouxi.slint.lang.psi.SlintPsiKeyword
class KeywordHighlightAnnotator : Annotator { class KeywordHighlightAnnotator : Annotator {
override fun annotate(element: PsiElement, holder: AnnotationHolder) { override fun annotate(element: PsiElement, holder: AnnotationHolder) {
@@ -17,13 +16,6 @@ class KeywordHighlightAnnotator : Annotator {
.create() .create()
return return
} }
if (element is SlintPsiKeyword) {
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
.range(element)
.textAttributes(Definitions._KeyWord)
.create()
return
}
if (element is SlintTypeRef && SlintPsiUtils.isInternalType(element)) { if (element is SlintTypeRef && SlintPsiUtils.isInternalType(element)) {
holder.newSilentAnnotation(HighlightSeverity.INFORMATION) holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
.range(element) .range(element)
@@ -40,7 +32,7 @@ class KeywordHighlightAnnotator : Annotator {
} }
if (element is SlintProperty) { if (element is SlintProperty) {
holder.newSilentAnnotation(HighlightSeverity.INFORMATION) holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
.range(element.identifier!!) .range(element.identifier)
.textAttributes(DefaultLanguageHighlighterColors.INSTANCE_FIELD) .textAttributes(DefaultLanguageHighlighterColors.INSTANCE_FIELD)
.create() .create()
return return

View File

@@ -4,7 +4,6 @@ import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFileFactory import com.intellij.psi.PsiFileFactory
import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.util.PsiTreeUtil
import com.intellij.psi.util.nextLeafs
import me.zhouxi.slint.lang.psi.SlintComponent import me.zhouxi.slint.lang.psi.SlintComponent
import me.zhouxi.slint.lang.psi.SlintFile import me.zhouxi.slint.lang.psi.SlintFile
import me.zhouxi.slint.lang.psi.SlintImportSpecifier import me.zhouxi.slint.lang.psi.SlintImportSpecifier

View File

@@ -1,29 +0,0 @@
package me.zhouxi.slint.lang.psi.builder
import com.intellij.lang.PsiBuilder
import com.intellij.lang.impl.DelegateMarker
import com.intellij.lang.impl.PsiBuilderAdapter
import com.intellij.psi.tree.IElementType
/**
* @author zhouxi 2024/5/29
*/
class SlintPsiBuilder(delegate: PsiBuilder) : PsiBuilderAdapter(delegate) {
override fun mark(): PsiBuilder.Marker {
return SlintMarker(super.mark())
}
/**
* @author zhouxi 2024/5/29
*/
class SlintMarker(delegate: PsiBuilder.Marker) : DelegateMarker(delegate) {
override fun precede(): PsiBuilder.Marker {
return SlintMarker(super.precede())
}
override fun done(type: IElementType) {
println(type)
super.done(type)
}
}
}

View File

@@ -5,7 +5,6 @@ import com.intellij.openapi.util.NlsSafe
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.util.IncorrectOperationException import com.intellij.util.IncorrectOperationException
import me.zhouxi.slint.lang.createIdentifier import me.zhouxi.slint.lang.createIdentifier
import me.zhouxi.slint.lang.psi.SlintNamed
import me.zhouxi.slint.lang.psi.SlintPsiNamedElement import me.zhouxi.slint.lang.psi.SlintPsiNamedElement
import me.zhouxi.slint.lang.psi.SlintTypes import me.zhouxi.slint.lang.psi.SlintTypes

View File

@@ -1,7 +1,5 @@
package me.zhouxi.slint.lang.psi.stubs.stub.impl package me.zhouxi.slint.lang.psi.stubs.stub.impl
import com.intellij.psi.stubs.IStubElementType
import com.intellij.psi.stubs.StubBase
import com.intellij.psi.stubs.StubElement import com.intellij.psi.stubs.StubElement
import com.intellij.util.BitUtil import com.intellij.util.BitUtil
import me.zhouxi.slint.lang.psi.SlintProperty import me.zhouxi.slint.lang.psi.SlintProperty

View File

@@ -26,7 +26,7 @@ object SlintComponentElementType :
override fun createStub(psi: SlintComponent, parentStub: StubElement<out PsiElement?>): SlintComponentStub { override fun createStub(psi: SlintComponent, parentStub: StubElement<out PsiElement?>): SlintComponentStub {
return SlintComponentStubImpl( return SlintComponentStubImpl(
parentStub, parentStub,
psi.exportKeyword != null, false,
psi.identifier!!.text psi.identifier!!.text
) )
} }
@@ -49,14 +49,13 @@ object SlintComponentElementType :
} }
override fun createStub(tree: LighterAST, node: LighterASTNode, parentStub: StubElement<*>): SlintComponentStub { override fun createStub(tree: LighterAST, node: LighterASTNode, parentStub: StubElement<*>): SlintComponentStub {
val exported = tree.getChildren(node).any { it.tokenType == ExportKeyword }
val token = tree.getChildren(node).find { it.tokenType == IDENTIFIER } val token = tree.getChildren(node).find { it.tokenType == IDENTIFIER }
?.let { ?.let {
val text = it as LighterASTTokenNode val text = it as LighterASTTokenNode
tree.charTable.intern(text.text) tree.charTable.intern(text.text)
} }
return SlintComponentStubImpl(parentStub, exported, token.toString()) return SlintComponentStubImpl(parentStub, false, token.toString())
} }
override fun indexStub(stub: SlintComponentStub, sink: IndexSink) { override fun indexStub(stub: SlintComponentStub, sink: IndexSink) {

View File

@@ -19,14 +19,7 @@ object SlintPropertyElementType :
ILightStubElementType<SlintPropertyStub, SlintProperty?>("SlintProperty", SlintLanguage.INSTANCE) { ILightStubElementType<SlintPropertyStub, SlintProperty?>("SlintProperty", SlintLanguage.INSTANCE) {
override fun createStub(tree: LighterAST, node: LighterASTNode, parentStub: StubElement<*>): SlintPropertyStub { override fun createStub(tree: LighterAST, node: LighterASTNode, parentStub: StubElement<*>): SlintPropertyStub {
val children = tree.getChildren(node) val children = tree.getChildren(node)
val modifierNode = children.firstOrNull { it.tokenType == PropertyModifier }?.let { val modifierNode = 0
when (tree.getChildren(it)[0].tokenType) {
InKeyword -> 1
OutKeyword -> 2
InOutKeyword -> 3
else -> 0
}
} ?: 0
val name = children.first { it.tokenType == IDENTIFIER } as LighterASTTokenNode val name = children.first { it.tokenType == IDENTIFIER } as LighterASTTokenNode
return SlintPropertyStubImpl( return SlintPropertyStubImpl(
parentStub, parentStub,
@@ -47,11 +40,8 @@ object SlintPropertyElementType :
psi: SlintProperty, psi: SlintProperty,
parentStub: StubElement<out PsiElement?> parentStub: StubElement<out PsiElement?>
): SlintPropertyStub { ): SlintPropertyStub {
val modifier = psi.propertyModifier val name = psi.identifier.text
val isIn = modifier?.inKeyword != null || modifier?.inOutKeyword != null val flag: Short = 0
val isOut = modifier?.outKeyword != null || modifier?.inOutKeyword != null
val name = psi.identifier!!.text
val flag = SlintPropertyStubImpl.pack(isIn, isOut)
return SlintPropertyStubImpl(parentStub, flag, name) return SlintPropertyStubImpl(parentStub, flag, name)
} }

View File

@@ -4,12 +4,6 @@ import com.intellij.psi.tree.IElementType
import com.intellij.psi.tree.TokenSet import com.intellij.psi.tree.TokenSet
import me.zhouxi.slint.lang.psi.SlintTypes import me.zhouxi.slint.lang.psi.SlintTypes
val keywords = TokenSet.create(*SlintTypes::class.java.declaredFields
.filter { it.name.endsWith("Keyword") }
.map { it.get(null) as IElementType }.toTypedArray()
)
val braces = TokenSet.create( val braces = TokenSet.create(
SlintTypes.LBrace, SlintTypes.LBrace,
SlintTypes.LParent, SlintTypes.LParent,

View File

@@ -1,12 +1,11 @@
package me.zhouxi.slint.preview package me.zhouxi.slint.preview
import com.intellij.execution.RunManager
import com.intellij.openapi.actionSystem.AnAction import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.actionSystem.AnActionEvent
class PreviewAction : AnAction() { class PreviewAction : AnAction() {
override fun actionPerformed(e: AnActionEvent) { override fun actionPerformed(e: AnActionEvent) {
val manager = RunManager.getInstance(e.project!!) // val manager = RunManager.getInstance(e.project!!)
// e.si // e.si
// manager.createConfiguration() // manager.createConfiguration()

View File

@@ -21,10 +21,10 @@ object PropertyReferenceProvider : PsiReferenceProvider() {
val subComponent = element.parentOfType<SlintSubComponent>() val subComponent = element.parentOfType<SlintSubComponent>()
if (subComponent != null) { if (subComponent != null) {
val component = subComponent.resolve() ?: return null val component = subComponent.resolve() ?: return null
return component.inheritsProperties().find { it.identifier?.textMatches(element) == true } return component.inheritsProperties().find { it.identifier.textMatches(element) }
} }
val component = element.parentOfType<SlintComponent>() ?: return null val component = element.parentOfType<SlintComponent>() ?: return null
return component.inheritsProperties().find { it.identifier?.textMatches(element) == true } return component.inheritsProperties().find { it.identifier.textMatches(element) }
} }
} }
} }