fix: 语法问题
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("java")
|
id("java")
|
||||||
id("org.jetbrains.kotlin.jvm") version "1.9.23"
|
id("org.jetbrains.kotlin.jvm") version "1.9.23"
|
||||||
id("org.jetbrains.intellij") version "1.17.2"
|
id("org.jetbrains.intellij") version "1.17.3"
|
||||||
id("org.jetbrains.grammarkit") version "2022.3.2.2"
|
id("org.jetbrains.grammarkit") version "2022.3.2.2"
|
||||||
id("de.undercouch.download") version "5.6.0"
|
id("de.undercouch.download") version "5.6.0"
|
||||||
}
|
}
|
||||||
@@ -9,16 +9,16 @@ val slintVersion: String by project
|
|||||||
//github url
|
//github url
|
||||||
val slintGithubUrl = "https://github.com/slint-ui/slint/releases/download/v$slintVersion"
|
val slintGithubUrl = "https://github.com/slint-ui/slint/releases/download/v$slintVersion"
|
||||||
//download dir
|
//download dir
|
||||||
val slintViewerDownloadDir = "${layout.buildDirectory.get()}/slint-viewer"
|
val slintViewerDownloadDir = "${layout.buildDirectory.get()}/slint-lsp"
|
||||||
//decompression path
|
//decompression path
|
||||||
val slintViewerBinaryDir = "${layout.buildDirectory.get()}/slint-viewer/$slintVersion"
|
val slintViewerBinaryDir = "${layout.buildDirectory.get()}/slint-lsp/$slintVersion"
|
||||||
|
|
||||||
val grammarGeneratedRoot = "${layout.buildDirectory.get()}/generated/sources/grammar/"
|
val grammarGeneratedRoot = "${layout.buildDirectory.get()}/generated/sources/grammar/"
|
||||||
//github filename-> decompression name
|
//github filename-> decompression name
|
||||||
val slintViewerFilenames = arrayOf(
|
val slintViewerFilenames = arrayOf(
|
||||||
"slint-viewer-linux.tar.gz" to "slint-viewer-linux",
|
"slint-lsp-linux.tar.gz" to "slint-lsp-linux",
|
||||||
"slint-viewer-macos.tar.gz" to "slint-viewer-macos",
|
"slint-lsp-macos.tar.gz" to "slint-lsp-macos",
|
||||||
"slint-viewer-windows.zip" to "slint-viewer-windows.exe",
|
"slint-lsp-windows.zip" to "slint-lsp-windows.exe",
|
||||||
)
|
)
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
@@ -36,22 +36,17 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
intellij {
|
intellij {
|
||||||
version.set("IC-2023.2.5")
|
version.set("IU-2024.1")
|
||||||
sandboxDir.set("idea-sandbox")
|
sandboxDir.set("idea-sandbox")
|
||||||
plugins.set(listOf("java","Kotlin"))
|
plugins.set(listOf("java"))
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly("org.projectlombok:lombok:1.18.32")
|
|
||||||
annotationProcessor("org.projectlombok:lombok:1.18.32")
|
|
||||||
testCompileOnly("org.projectlombok:lombok:1.18.32")
|
|
||||||
testAnnotationProcessor("org.projectlombok:lombok:1.18.32")
|
|
||||||
// implementation("org.jetbrains:grammar-kit:2022.3.2")
|
|
||||||
}
|
}
|
||||||
tasks {
|
tasks {
|
||||||
buildPlugin {
|
buildPlugin {
|
||||||
//copy slint-viewer to plugin dir
|
//copy slint-lsp to plugin dir
|
||||||
from(slintViewerBinaryDir) {
|
from(slintViewerBinaryDir) {
|
||||||
into("/slint-viewer")
|
into("/slint-lsp")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
withType<JavaExec>().configureEach {
|
withType<JavaExec>().configureEach {
|
||||||
@@ -61,11 +56,11 @@ tasks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
runIde {
|
runIde {
|
||||||
//copy slint-viewer
|
//copy slint-lsp
|
||||||
doFirst {
|
doFirst {
|
||||||
copy {
|
copy {
|
||||||
from(slintViewerBinaryDir)
|
from(slintViewerBinaryDir)
|
||||||
into("idea-sandbox/plugins/intellij-slint/slint-viewer")
|
into("idea-sandbox/plugins/intellij-slint/slint-lsp")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,7 +95,7 @@ tasks {
|
|||||||
jvmArgs("-Djava.awt.headless=true")
|
jvmArgs("-Djava.awt.headless=true")
|
||||||
}
|
}
|
||||||
|
|
||||||
register("downloadSlintViewer") {
|
register("downloadSlintResource") {
|
||||||
doFirst {
|
doFirst {
|
||||||
slintViewerFilenames.forEach { fileDesc ->
|
slintViewerFilenames.forEach { fileDesc ->
|
||||||
val (filename, renamed) = fileDesc
|
val (filename, renamed) = fileDesc
|
||||||
@@ -118,7 +113,7 @@ tasks {
|
|||||||
}
|
}
|
||||||
from(fileTree)
|
from(fileTree)
|
||||||
//include executable file path
|
//include executable file path
|
||||||
include("slint-viewer/slint-viewer*")
|
include("slint-lsp/slint-lsp*")
|
||||||
eachFile {
|
eachFile {
|
||||||
//rename to platform name
|
//rename to platform name
|
||||||
this.relativePath = RelativePath(true, renamed)
|
this.relativePath = RelativePath(true, renamed)
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
Percent = "%"
|
Percent = "%"
|
||||||
Whitespace = "regexp:(\s+)"
|
Whitespace = "regexp:(\s+)"
|
||||||
NumberLiteral = "regexp:\d+(\.(\d+)?)?([a-z]+|%)?"
|
NumberLiteral = "regexp:\d+(\.(\d+)?)?([a-z]+|%)?"
|
||||||
Identifier = "regexp:^[a-zA-Z_][A-Za-z0-9\-_]*"
|
IDENTIFIER = "regexp:^[a-zA-Z_][A-Za-z0-9\-_]*"
|
||||||
ColorLiteral = "regexp:#([a-zA-Z0-9]+)"
|
ColorLiteral = "regexp:#([a-zA-Z0-9]+)"
|
||||||
StringLiteral = 'regexp:(^"[^"\r\n]*")'
|
StringLiteral = 'regexp:(^"[^"\r\n]*")'
|
||||||
LineComment = 'regexp:^//[^\r\n]*'
|
LineComment = 'regexp:^//[^\r\n]*'
|
||||||
@@ -70,26 +70,25 @@ 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 ComponentName '{' ComponentElement* '}' {
|
GlobalSingleton ::= ExportKeyword? GlobalKeyword 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|ImportResource)';'{
|
Import ::= ImportKeyword (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 ModuleLocation{
|
ImportElement ::= '{' ImportSpecifier (',' ImportSpecifier)* '}' FromKeyword ModuleRef{
|
||||||
pin=1
|
pin=1
|
||||||
}
|
}
|
||||||
ImportResource ::= ModuleLocation
|
|
||||||
|
|
||||||
// ABc as Def
|
// ABc as Def
|
||||||
ImportSpecifier ::= ReferenceIdentifier ImportAlias?{
|
ImportSpecifier ::= ComponentRef ImportAlias?{
|
||||||
pin=1
|
pin=1
|
||||||
elementTypeFactory="me.zhouxi.slint.lang.psi.stubs.types.SlintStubTypes.importSpecifier"
|
elementTypeFactory="me.zhouxi.slint.lang.psi.stubs.types.SlintStubTypes.importSpecifier"
|
||||||
stubClass="me.zhouxi.slint.lang.psi.stubs.stub.SlintImportSpecifierStub"
|
stubClass="me.zhouxi.slint.lang.psi.stubs.stub.SlintImportSpecifierStub"
|
||||||
@@ -97,21 +96,21 @@ ImportSpecifier ::= ReferenceIdentifier ImportAlias?{
|
|||||||
}
|
}
|
||||||
private AliasNameRecover::=!(','|'}'|';')
|
private AliasNameRecover::=!(','|'}'|';')
|
||||||
|
|
||||||
ImportAlias ::= AsKeyword InternalName {
|
ImportAlias ::= AsKeyword 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 TypeName (':=')? StructBody {
|
Struct ::= ExportKeyword? StructKeyword Identifier (':=')? StructBody {
|
||||||
pin=2
|
pin=2
|
||||||
}
|
}
|
||||||
private StructBody ::= '{' FieldDeclarations? '}'{
|
private StructBody ::= '{' FieldDeclarations? '}'{
|
||||||
pin=1
|
pin=1
|
||||||
}
|
}
|
||||||
//EnumDeclaration
|
//EnumDeclaration
|
||||||
Enum ::= ExportKeyword? EnumKeyword EnumName '{' (EnumValue (','EnumValue)*','? )? '}'{
|
Enum ::= ExportKeyword? EnumKeyword 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"
|
||||||
@@ -125,19 +124,19 @@ Export ::= ExportKeyword (ExportType | ExportModule) {
|
|||||||
ExportType ::= '{' ExportSpecifier (','ExportSpecifier)* ','? '}'{
|
ExportType ::= '{' ExportSpecifier (','ExportSpecifier)* ','? '}'{
|
||||||
pin=1
|
pin=1
|
||||||
}
|
}
|
||||||
ExportSpecifier::= ReferenceIdentifier ExportAlias?{
|
ExportSpecifier::= ComponentRef ExportAlias?{
|
||||||
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"
|
||||||
}
|
}
|
||||||
ExportAlias ::= AsKeyword ExternalName{
|
ExportAlias ::= AsKeyword Identifier{
|
||||||
pin=1
|
pin=1
|
||||||
}
|
}
|
||||||
ExportModule ::= '*' FromKeyword ModuleLocation ';'{
|
ExportModule ::= '*' FromKeyword ModuleRef ';'{
|
||||||
pin=1
|
pin=1
|
||||||
}
|
}
|
||||||
|
|
||||||
Component ::= ExportKeyword? ComponentKeyword ComponentName InheritDeclaration? '{' ComponentElement* '}' {
|
Component ::= ExportKeyword? ComponentKeyword Identifier InheritDeclaration? '{' ComponentElement* '}' {
|
||||||
pin=2
|
pin=2
|
||||||
implements=[
|
implements=[
|
||||||
"me.zhouxi.slint.lang.psi.SlintPsiNamedElement"
|
"me.zhouxi.slint.lang.psi.SlintPsiNamedElement"
|
||||||
@@ -148,7 +147,7 @@ Component ::= ExportKeyword? ComponentKeyword ComponentName InheritDeclaration?
|
|||||||
}
|
}
|
||||||
//组件定义
|
//组件定义
|
||||||
//private LegacyComponent ::= (ComponentName|NamedIdentifier ':=' ) ComponentBody
|
//private LegacyComponent ::= (ComponentName|NamedIdentifier ':=' ) ComponentBody
|
||||||
InheritDeclaration ::= InheritsKeyword ReferenceIdentifier {
|
InheritDeclaration ::= InheritsKeyword ComponentRef {
|
||||||
pin=1
|
pin=1
|
||||||
recoverWhile=recoverInherit
|
recoverWhile=recoverInherit
|
||||||
}
|
}
|
||||||
@@ -157,18 +156,18 @@ private recoverInherit::=!('{')
|
|||||||
private ComponentElement ::=ChildrenPlaceholder| Property | Callback
|
private ComponentElement ::=ChildrenPlaceholder| Property | Callback
|
||||||
| Function | PropertyAnimation | CallbackConnection | Transitions
|
| Function | PropertyAnimation | CallbackConnection | Transitions
|
||||||
| PropertyChanged
|
| PropertyChanged
|
||||||
| States | TwoWayBinding|PropertyBinding | ConditionalElement
|
| States | TwoWayBinding | ConditionalElement
|
||||||
| RepetitionElement | SubComponent {
|
| RepetitionElement | SubComponent | PropertyBinding {
|
||||||
recoverWhile(".*")=recoverWhileForComponentBody
|
recoverWhile=recoverWhileForComponentBody
|
||||||
}
|
}
|
||||||
private recoverWhileForComponentBody::= !('{'|';'|'}'|'@'|GenericIdentifier)
|
private recoverWhileForComponentBody::= !('{'|';'|'}'|'@'|Identifier)
|
||||||
|
|
||||||
ChildrenPlaceholder ::= '@' 'children'{
|
ChildrenPlaceholder ::= '@' 'children'{
|
||||||
pin=1
|
pin=1
|
||||||
}
|
}
|
||||||
//--------------------------------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 '>')? PropertyName(PropertyValue|PropertyTwoWayBindingValue|';'){
|
Property ::= PropertyModifier? PropertyKeyword ('<' Type '>')? Identifier (PropertyValue|PropertyTwoWayBindingValue|';'){
|
||||||
pin=2
|
pin=2
|
||||||
implements=[
|
implements=[
|
||||||
"me.zhouxi.slint.lang.psi.SlintPsiNamedElement"
|
"me.zhouxi.slint.lang.psi.SlintPsiNamedElement"
|
||||||
@@ -181,7 +180,7 @@ PropertyModifier ::= InKeyword|OutKeyword|InOutKeyword|PrivateKeyword
|
|||||||
private PropertyValue::= ':' BindingStatement {
|
private PropertyValue::= ':' BindingStatement {
|
||||||
pin=1
|
pin=1
|
||||||
}
|
}
|
||||||
private PropertyTwoWayBindingValue ::= '<=>' QualifiedPropertyNameReference ';' {
|
private PropertyTwoWayBindingValue ::= '<=>' QualifiedPropertyRef ';' {
|
||||||
pin=1
|
pin=1
|
||||||
}
|
}
|
||||||
//--------------------------------PropertyChanged Start----------------------------------------------------
|
//--------------------------------PropertyChanged Start----------------------------------------------------
|
||||||
@@ -190,29 +189,29 @@ PropertyChanged ::= ChangedKeyword LocalVariable '=>' CodeBlock{
|
|||||||
}
|
}
|
||||||
//--------------------------------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 FunctionName CallbackBinding? ';'{
|
Callback ::= PureKeyword? CallbackKeyword Identifier 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 | ('<=>'QualifiedPropertyNameReference)
|
CallbackBinding::= CallbackArgument | ('<=>'QualifiedPropertyRef)
|
||||||
//入参定义
|
//入参定义
|
||||||
CallbackArgument ::= '(' (Type (','Type)* ','? )? ')' ReturnType?{
|
CallbackArgument ::= '(' (Type (','Type)* ','? )? ')' ReturnType?{
|
||||||
pin=1
|
pin=1
|
||||||
}
|
}
|
||||||
private ReturnType ::= '->' (NamedType|ArrayType){
|
private ReturnType ::= '->' (QualifiedTypeRef|ArrayType){
|
||||||
pin=1
|
pin=1
|
||||||
}
|
}
|
||||||
//--------------------------------TwoWayBindingDeclaration Start----------------------------------------------------
|
//--------------------------------TwoWayBindingDeclaration Start----------------------------------------------------
|
||||||
//组件双向绑定
|
//组件双向绑定
|
||||||
TwoWayBinding ::= ReferenceIdentifier '<=>' QualifiedPropertyNameReference ';' {
|
TwoWayBinding ::= PropertyRef '<=>' QualifiedPropertyRef ';' {
|
||||||
pin=2
|
pin=2
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------FunctionDeclaration Start----------------------------------------------------
|
//--------------------------------FunctionDeclaration Start----------------------------------------------------
|
||||||
//函数定义 protected? pure? function f()
|
//函数定义 protected? pure? function f()
|
||||||
Function ::= FunctionModifiers? FunctionKeyword FunctionName FunctionArguments ReturnType? CodeBlock{
|
Function ::= FunctionModifiers? FunctionKeyword Identifier FunctionArguments ReturnType? CodeBlock{
|
||||||
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"
|
||||||
@@ -225,7 +224,7 @@ private FunctionArguments ::= '(' FieldDeclarations* ')'{
|
|||||||
|
|
||||||
//--------------------------------CallbackConnectionDeclaration Start---------------------------------------------------
|
//--------------------------------CallbackConnectionDeclaration Start---------------------------------------------------
|
||||||
//回调绑定定义 abc()=> {}
|
//回调绑定定义 abc()=> {}
|
||||||
CallbackConnection ::= FunctionReference CallbackConnectionArguments? '=>' CodeBlock ';'?{
|
CallbackConnection ::= FunctionRef CallbackConnectionArguments? '=>' CodeBlock ';'?{
|
||||||
pin=3
|
pin=3
|
||||||
}
|
}
|
||||||
private CallbackConnectionArguments ::= '(' (LocalVariable (',' LocalVariable)* ','?)? ')'
|
private CallbackConnectionArguments ::= '(' (LocalVariable (',' LocalVariable)* ','?)? ')'
|
||||||
@@ -245,10 +244,11 @@ RepetitionIndex ::= '[' LocalVariable ']'{
|
|||||||
}
|
}
|
||||||
//--------------------------------SubElementDeclaration Start---------------------------------------------------
|
//--------------------------------SubElementDeclaration Start---------------------------------------------------
|
||||||
//子组件结构元素定义
|
//子组件结构元素定义
|
||||||
SubComponent ::= (PropertyName ':=')? ReferenceIdentifier '{' ComponentElement* '}'{
|
SubComponent ::= (Identifier ':=')? ComponentRef '{' ComponentElement* '}'{
|
||||||
pin=3
|
pin=3
|
||||||
recoverWhile=recoverWhileForComponentBody
|
// recoverWhile=recoverForBrace
|
||||||
}
|
}
|
||||||
|
//private recoverForBrace::=!'}'
|
||||||
|
|
||||||
//--------------------------------TransitionsDeclaration Start---------------------------------------------------
|
//--------------------------------TransitionsDeclaration Start---------------------------------------------------
|
||||||
//过渡绑定
|
//过渡绑定
|
||||||
@@ -272,7 +272,7 @@ State ::= LocalVariable StateCondition? ':' '{' StateItem* '}' {
|
|||||||
extends="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl"
|
extends="me.zhouxi.slint.lang.psi.impl.SlintPsiNamedElementImpl"
|
||||||
recoverWhile=recoverForRBracket
|
recoverWhile=recoverForRBracket
|
||||||
}
|
}
|
||||||
private recoverForRBracket::=!(']'|'}'|';'|GenericIdentifier)
|
private recoverForRBracket::=!(']'|'}'|';'|Identifier)
|
||||||
StateCondition ::= WhenKeyword Expression {
|
StateCondition ::= WhenKeyword Expression {
|
||||||
pin=1
|
pin=1
|
||||||
}
|
}
|
||||||
@@ -283,12 +283,11 @@ StateTransition ::= (InKeyword|OutKeyword) ':' '{' PropertyAnimation* '}'{
|
|||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------
|
||||||
//类型定义
|
//类型定义
|
||||||
Type ::= NamedType | UnnamedType | ArrayType
|
Type ::= QualifiedTypeRef | UnnamedType | ArrayType
|
||||||
private NamedType ::= QualifiedTypeNameReference
|
|
||||||
ArrayType ::= '[' Type ']'
|
ArrayType ::= '[' Type ']'
|
||||||
UnnamedType ::= '{' FieldDeclarations* '}'
|
UnnamedType ::= '{' FieldDeclarations* '}'
|
||||||
private FieldDeclarations ::= FieldDeclaration (',' FieldDeclaration)* ','?
|
private FieldDeclarations ::= FieldDeclaration (',' FieldDeclaration)* ','?
|
||||||
private FieldDeclaration ::= PropertyName ':' Type
|
private FieldDeclaration ::= Identifier ':' Type
|
||||||
|
|
||||||
|
|
||||||
//代码块
|
//代码块
|
||||||
@@ -320,18 +319,17 @@ ElseStatement ::= ElseKeyword CodeBlock {
|
|||||||
pin=1
|
pin=1
|
||||||
}
|
}
|
||||||
//动画定义
|
//动画定义
|
||||||
PropertyAnimation ::= AnimateKeyword ('*'| (QualifiedPropertyNameReference (',' QualifiedPropertyNameReference)*)) '{' QualifiedNamePropertyBinding*'}'{
|
PropertyAnimation ::= AnimateKeyword ('*'| (QualifiedPropertyRef (',' QualifiedPropertyRef)*)) '{' QualifiedNamePropertyBinding*'}'{
|
||||||
pin=1
|
pin=1
|
||||||
}
|
}
|
||||||
//组件属性绑定 name: xxx ; name : {}; name : {}
|
//组件属性绑定 name: xxx ; name : {}; name : {}
|
||||||
//只有对象定义和表达式需要 ;
|
//只有对象定义和表达式需要 ;
|
||||||
private QualifiedNamePropertyBinding::= QualifiedPropertyNameReference ':' BindingStatement{
|
private QualifiedNamePropertyBinding::= QualifiedPropertyRef ':' BindingStatement{
|
||||||
pin=2
|
pin=2
|
||||||
}
|
}
|
||||||
PropertyBinding ::= ReferenceIdentifier ':' BindingStatement{
|
PropertyBinding ::= PropertyRef ':' BindingStatement{
|
||||||
pin=2
|
|
||||||
}
|
}
|
||||||
private WhileIdentifier::=!('}'|';'|GenericIdentifier)
|
private WhileIdentifier::=!('}'|';'|Identifier)
|
||||||
//优先尝试表达式解析 {}属于代码块 {name:xx}属于表达式,那么需要预测后面两个token,第二个token不是':'的情况下才是代码块
|
//优先尝试表达式解析 {}属于代码块 {name:xx}属于表达式,那么需要预测后面两个token,第二个token不是':'的情况下才是代码块
|
||||||
//所以优先判断对象创建判断,然后进行代码块判断,最后进行表达式
|
//所以优先判断对象创建判断,然后进行代码块判断,最后进行表达式
|
||||||
//代码块分号可选
|
//代码块分号可选
|
||||||
@@ -365,7 +363,7 @@ Expression ::= AtExpression
|
|||||||
{
|
{
|
||||||
recoverWhile=recoverForExpression
|
recoverWhile=recoverForExpression
|
||||||
}
|
}
|
||||||
private recoverForExpression ::= !(Expression|GenericIdentifier|';')
|
private recoverForExpression ::= !(Expression|Identifier|';')
|
||||||
|
|
||||||
private BinaryExpression ::= SelfAssignExpression | ComparisonExpression | BooleanExpression
|
private BinaryExpression ::= SelfAssignExpression | ComparisonExpression | BooleanExpression
|
||||||
//加法表达式
|
//加法表达式
|
||||||
@@ -446,7 +444,7 @@ ParenthesizedExpression ::= '(' Expression ')'{
|
|||||||
pin=2
|
pin=2
|
||||||
}
|
}
|
||||||
//fake PropertySuffixExpression::= Expression? '.' GenericIdentifier
|
//fake PropertySuffixExpression::= Expression? '.' GenericIdentifier
|
||||||
PropertyExpression ::= Expression '.' GenericIdentifier {
|
PropertyExpression ::= Expression '.' Identifier {
|
||||||
// pin=2 extends=PropertySuffixExpression elementType=PropertySuffixExpression
|
// pin=2 extends=PropertySuffixExpression elementType=PropertySuffixExpression
|
||||||
}
|
}
|
||||||
FunctionInvocationExpression ::= Expression '(' InvocationArguments? ')'{
|
FunctionInvocationExpression ::= Expression '(' InvocationArguments? ')'{
|
||||||
@@ -465,7 +463,7 @@ ArrayCreationExpression ::= '[' ArrayElements* ']'{
|
|||||||
private ArrayElements ::= Expression (','Expression)* ','?
|
private ArrayElements ::= Expression (','Expression)* ','?
|
||||||
|
|
||||||
|
|
||||||
LiteralExpression ::= Numbers | RawStringLiteral | GenericIdentifier | RawColorLiteral
|
LiteralExpression ::= Numbers | RawStringLiteral | Identifier | RawColorLiteral
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
@@ -477,7 +475,7 @@ ObjectCreationExpression ::= '{' ObjectPropertyBindings '}'{
|
|||||||
private ObjectPropertyBindings ::= ObjectPropertyBinding (','ObjectPropertyBinding)* ','?{
|
private ObjectPropertyBindings ::= ObjectPropertyBinding (','ObjectPropertyBinding)* ','?{
|
||||||
pin=1
|
pin=1
|
||||||
}
|
}
|
||||||
private ObjectPropertyBinding ::= PropertyName ':' Expression{
|
private ObjectPropertyBinding ::= Identifier ':' Expression{
|
||||||
pin=2
|
pin=2
|
||||||
recoverWhile=recover
|
recoverWhile=recover
|
||||||
}
|
}
|
||||||
@@ -513,55 +511,35 @@ PrivateKeyword::='private'
|
|||||||
ReturnKeyword::='return'
|
ReturnKeyword::='return'
|
||||||
//---------NamedIdentifier ,简化PsiTree-----------------------------------
|
//---------NamedIdentifier ,简化PsiTree-----------------------------------
|
||||||
//noinspection BnfUnusedRule 用于标记命名节点对应的identifier
|
//noinspection BnfUnusedRule 用于标记命名节点对应的identifier
|
||||||
Named ::= PropertyName | TypeName |ExternalName | InternalName|ComponentName|FunctionName{
|
LocalVariable ::= Identifier{
|
||||||
pin=1
|
|
||||||
}
|
|
||||||
{
|
|
||||||
extends("PropertyName|TypeName|ComponentName|FunctionName|InternalName|ExternalName")=Named
|
|
||||||
}
|
|
||||||
LocalVariable ::= GenericIdentifier{
|
|
||||||
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"]
|
||||||
}
|
}
|
||||||
FunctionName ::= GenericIdentifier
|
fake Referred::=Identifier{
|
||||||
|
extends="me.zhouxi.slint.lang.psi.impl.SlintRefIdentifierImpl"
|
||||||
ComponentName ::=GenericIdentifier
|
|
||||||
|
|
||||||
InternalName ::= GenericIdentifier
|
|
||||||
|
|
||||||
PropertyName ::= GenericIdentifier
|
|
||||||
|
|
||||||
TypeName ::= GenericIdentifier
|
|
||||||
|
|
||||||
EnumName ::= GenericIdentifier
|
|
||||||
|
|
||||||
EnumValue ::=GenericIdentifier
|
|
||||||
|
|
||||||
ExternalName ::=GenericIdentifier
|
|
||||||
|
|
||||||
ReferenceIdentifier::=GenericIdentifier{
|
|
||||||
extends="me.zhouxi.slint.lang.psi.impl.SlintReferencedIdentifierImpl"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------UnnamedIdentifier------------------
|
ComponentRef::=Identifier{
|
||||||
|
extends=Referred
|
||||||
PropertyNameReference ::= GenericIdentifier{
|
|
||||||
extends="me.zhouxi.slint.lang.psi.impl.SlintReferencedIdentifierImpl"
|
|
||||||
}
|
}
|
||||||
FunctionReference ::=GenericIdentifier{
|
QualifiedPropertyRef ::= PropertyRef ('.' PropertyRef)*{
|
||||||
|
extends=PropertyRef
|
||||||
}
|
}
|
||||||
QualifiedPropertyNameReference ::= PropertyNameReference ('.' PropertyNameReference)*{
|
PropertyRef ::= Identifier{
|
||||||
extends=PropertyNameReference
|
extends=Referred
|
||||||
}
|
}
|
||||||
TypeNameReference::=GenericIdentifier
|
QualifiedTypeRef::= TypeRef ('.' TypeRef)*{
|
||||||
|
extends=TypeRef
|
||||||
QualifiedTypeNameReference ::= TypeNameReference ('.' TypeNameReference)*{
|
|
||||||
extends=TypeNameReference
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ModuleLocation ::= RawStringLiteral{
|
TypeRef::=Identifier{
|
||||||
extends="me.zhouxi.slint.lang.psi.impl.SlintReferencedIdentifierImpl"
|
extends=Referred
|
||||||
|
}
|
||||||
|
FunctionRef::=Identifier{
|
||||||
|
extends=Referred
|
||||||
|
}
|
||||||
|
ModuleRef::=RawStringLiteral{
|
||||||
|
extends=Referred
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
//noinspection BnfSuspiciousToken
|
//noinspection BnfSuspiciousToken
|
||||||
@@ -571,7 +549,7 @@ private RawStringLiteral ::= StringLiteral
|
|||||||
private Numbers ::= NumberLiteral
|
private Numbers ::= NumberLiteral
|
||||||
|
|
||||||
//noinspection BnfSuspiciousToken
|
//noinspection BnfSuspiciousToken
|
||||||
private GenericIdentifier::= Identifier
|
private Identifier::= IDENTIFIER
|
||||||
|
|
||||||
//noinspection BnfSuspiciousToken
|
//noinspection BnfSuspiciousToken
|
||||||
private RawColorLiteral ::= ColorLiteral
|
private RawColorLiteral ::= ColorLiteral
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ LINECOMMENT=\/\/[^\r\n]*
|
|||||||
"|" { return Pipe; }
|
"|" { return Pipe; }
|
||||||
"%" { return Percent; }
|
"%" { return Percent; }
|
||||||
{NUMBERLITERAL} { return NumberLiteral; }
|
{NUMBERLITERAL} { return NumberLiteral; }
|
||||||
{IDENTIFIER} { return Identifier; }
|
{IDENTIFIER} { return IDENTIFIER; }
|
||||||
{COLORLITERAL} { return ColorLiteral; }
|
{COLORLITERAL} { return ColorLiteral; }
|
||||||
{LINECOMMENT} { return LineComment; }
|
{LINECOMMENT} { return LineComment; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
{
|
|
||||||
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.impl.SlintPsiElementImpl"
|
|
||||||
elementTypeHolderClass="me.zhouxi.slint.lang.psi.SlintTypes"
|
|
||||||
elementTypeClass="me.zhouxi.slint.lang.SlintElementType"
|
|
||||||
tokenTypeClass="me.zhouxi.slint.lang.SlintTokenType"
|
|
||||||
psiClassPrefix="Slint"
|
|
||||||
psiImplClassSuffix="Impl"
|
|
||||||
psiPackage="me.zhouxi.slint.lang.psi"
|
|
||||||
psiImplPackage="me.zhouxi.slint.lang.psi.impl"
|
|
||||||
tokens=[
|
|
||||||
Comma = ","
|
|
||||||
FatArrow = "=>"
|
|
||||||
DoubleArrow = "<=>"
|
|
||||||
PlusEqual = "+="
|
|
||||||
MinusEqual = "-="
|
|
||||||
StarEqual = "*="
|
|
||||||
DivEqual = "/="
|
|
||||||
LessEqual = "<="
|
|
||||||
GreaterEqual = ">="
|
|
||||||
EqualEqual = "=="
|
|
||||||
NotEqual = "!="
|
|
||||||
ColonEqual = ":="
|
|
||||||
Arrow = "->"
|
|
||||||
OrOr = "||"
|
|
||||||
AndAnd = "&&"
|
|
||||||
LBrace = "{"
|
|
||||||
RBrace = "}"
|
|
||||||
LParent = "("
|
|
||||||
RParent = ")"
|
|
||||||
LAngle = "<"
|
|
||||||
RAngle = ">"
|
|
||||||
LBracket = "["
|
|
||||||
RBracket = "]"
|
|
||||||
Plus = "+"
|
|
||||||
Minus = "-"
|
|
||||||
Star = "*"
|
|
||||||
Div = "/"
|
|
||||||
Equal = "="
|
|
||||||
Colon = ":"
|
|
||||||
Comma = ","
|
|
||||||
Semicolon = ";"
|
|
||||||
Bang = "!"
|
|
||||||
Dot = "."
|
|
||||||
Question = "?"
|
|
||||||
Dollar = "$"
|
|
||||||
At = "@"
|
|
||||||
Pipe = "|"
|
|
||||||
Percent = "%"
|
|
||||||
Whitespace = "regexp:(\s+)"
|
|
||||||
NumberLiteral = "regexp:\d+(\.(\d+)?)?([a-z]+|%)?"
|
|
||||||
Identifier = "regexp:^[a-zA-Z_][A-Za-z0-9\-_]*"
|
|
||||||
ColorLiteral = "regexp:#([a-zA-Z0-9]+)"
|
|
||||||
StringLiteral = 'regexp:(^"[^"\r\n]*")'
|
|
||||||
LineComment = 'regexp:^//[^\r\n]*'
|
|
||||||
BlockComment = 'regexp:/\*[\s\S]*?\*/'
|
|
||||||
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
Document ::= Binding*
|
|
||||||
Binding ::=Identifier ':' Identifier ';'{
|
|
||||||
pin=2
|
|
||||||
recoverWhile=while
|
|
||||||
}
|
|
||||||
private while::=!(';'|Identifier)
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package me.zhouxi.slint.lang.psi;
|
||||||
|
|
||||||
|
public interface SlintPsiRefIdentifier extends SlintPsiElement {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package me.zhouxi.slint.lang.psi;
|
|
||||||
|
|
||||||
public interface SlintPsiReferencedIdentifier extends SlintPsiElement {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -3,12 +3,12 @@ package me.zhouxi.slint.lang.psi.impl;
|
|||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
import com.intellij.psi.PsiReference;
|
import com.intellij.psi.PsiReference;
|
||||||
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
|
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
|
||||||
import me.zhouxi.slint.lang.psi.SlintPsiReferencedIdentifier;
|
import me.zhouxi.slint.lang.psi.SlintPsiRefIdentifier;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public abstract class SlintReferencedIdentifierImpl extends SlintPsiElementImpl implements SlintPsiReferencedIdentifier {
|
public abstract class SlintRefIdentifierImpl extends SlintPsiElementImpl implements SlintPsiRefIdentifier {
|
||||||
|
|
||||||
public SlintReferencedIdentifierImpl(@NotNull ASTNode node) {
|
public SlintRefIdentifierImpl(@NotNull ASTNode node) {
|
||||||
super(node);
|
super(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9,9 +9,9 @@ import com.intellij.psi.stubs.IStubElementType
|
|||||||
import com.intellij.psi.stubs.StubElement
|
import com.intellij.psi.stubs.StubElement
|
||||||
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.SlintPsiElement
|
import me.zhouxi.slint.lang.psi.SlintPsiElement
|
||||||
import me.zhouxi.slint.lang.psi.SlintPsiNamedElement
|
import me.zhouxi.slint.lang.psi.SlintPsiNamedElement
|
||||||
|
import me.zhouxi.slint.lang.psi.SlintTypes
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author zhouxi 2024/5/23
|
* @author zhouxi 2024/5/23
|
||||||
@@ -24,7 +24,7 @@ abstract class SlintStubBasedPsiNamedElementImpl<T : StubElement<out PsiElement>
|
|||||||
constructor(stub: T, nodeType: IStubElementType<*, *>) : super(stub, nodeType)
|
constructor(stub: T, nodeType: IStubElementType<*, *>) : super(stub, nodeType)
|
||||||
|
|
||||||
override fun getNameIdentifier(): PsiElement? {
|
override fun getNameIdentifier(): PsiElement? {
|
||||||
return findChildByClass(SlintNamed::class.java)
|
return findChildByType(SlintTypes.IDENTIFIER)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getName(): String? {
|
override fun getName(): String? {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package me.zhouxi.slint.reference;
|
|||||||
import com.intellij.openapi.util.TextRange;
|
import com.intellij.openapi.util.TextRange;
|
||||||
import com.intellij.psi.AbstractElementManipulator;
|
import com.intellij.psi.AbstractElementManipulator;
|
||||||
import com.intellij.util.IncorrectOperationException;
|
import com.intellij.util.IncorrectOperationException;
|
||||||
import me.zhouxi.slint.lang.psi.SlintPsiReferencedIdentifier;
|
import me.zhouxi.slint.lang.psi.SlintPsiRefIdentifier;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -12,9 +12,9 @@ import static me.zhouxi.slint.lang.SlintElementFactoryKt.createIdentifier;
|
|||||||
/**
|
/**
|
||||||
* @author zhouxi 2024/5/8
|
* @author zhouxi 2024/5/8
|
||||||
*/
|
*/
|
||||||
public class SlintElementNameManipulator extends AbstractElementManipulator<SlintPsiReferencedIdentifier> {
|
public class SlintElementNameManipulator extends AbstractElementManipulator<SlintPsiRefIdentifier> {
|
||||||
@Override
|
@Override
|
||||||
public @Nullable SlintPsiReferencedIdentifier handleContentChange(@NotNull SlintPsiReferencedIdentifier element, @NotNull TextRange range, String newContent) throws IncorrectOperationException {
|
public @Nullable SlintPsiRefIdentifier handleContentChange(@NotNull SlintPsiRefIdentifier element, @NotNull TextRange range, String newContent) throws IncorrectOperationException {
|
||||||
final var identifier = element.getFirstChild();
|
final var identifier = element.getFirstChild();
|
||||||
if (identifier==null){
|
if (identifier==null){
|
||||||
throw new IncorrectOperationException("identifier doesn't exist");
|
throw new IncorrectOperationException("identifier doesn't exist");
|
||||||
@@ -26,7 +26,7 @@ public class SlintElementNameManipulator extends AbstractElementManipulator<Slin
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public TextRange getRangeInElement(@NotNull final SlintPsiReferencedIdentifier element) {
|
public TextRange getRangeInElement(@NotNull final SlintPsiRefIdentifier element) {
|
||||||
return new TextRange(0,element.getTextLength());
|
return new TextRange(0,element.getTextLength());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,12 +19,11 @@ 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)
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -19,12 +19,12 @@ class SlintCompletionAutoPopupHandler : TypedHandlerDelegate() {
|
|||||||
override fun checkAutoPopup(charTyped: Char, project: Project, editor: Editor, file: PsiFile): Result {
|
override fun checkAutoPopup(charTyped: Char, project: Project, editor: Editor, file: PsiFile): Result {
|
||||||
val lookup = LookupManager.getActiveLookup(editor) as LookupImpl?
|
val lookup = LookupManager.getActiveLookup(editor) as LookupImpl?
|
||||||
|
|
||||||
val phase = CompletionServiceImpl.getCompletionPhase()
|
val phase = CompletionServiceImpl.completionPhase
|
||||||
if (LOG.isDebugEnabled) {
|
if (LOG.isDebugEnabled) {
|
||||||
LOG.debug("checkAutoPopup: character=$charTyped;")
|
LOG.debug("checkAutoPopup: character=$charTyped;")
|
||||||
LOG.debug("phase=$phase")
|
LOG.debug("phase=$phase")
|
||||||
LOG.debug("lookup=$lookup")
|
LOG.debug("lookup=$lookup")
|
||||||
LOG.debug("currentCompletion=" + CompletionServiceImpl.getCompletionService().currentCompletion)
|
LOG.debug("currentCompletion=" + CompletionServiceImpl.completionService.currentCompletion)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lookup != null) {
|
if (lookup != null) {
|
||||||
|
|||||||
@@ -4,16 +4,20 @@ import com.intellij.codeInsight.completion.CompletionContributor
|
|||||||
import com.intellij.codeInsight.completion.CompletionParameters
|
import com.intellij.codeInsight.completion.CompletionParameters
|
||||||
import com.intellij.codeInsight.completion.CompletionType
|
import com.intellij.codeInsight.completion.CompletionType
|
||||||
import me.zhouxi.slint.completion.provider.*
|
import me.zhouxi.slint.completion.provider.*
|
||||||
|
import me.zhouxi.slint.completion.provider.ComponentNameProvider
|
||||||
|
import me.zhouxi.slint.completion.provider.SubComponentNameProvider
|
||||||
|
|
||||||
class SlintCompletionContributor : CompletionContributor() {
|
class SlintCompletionContributor : CompletionContributor() {
|
||||||
init {
|
init {
|
||||||
extend(TopKeywordProvider)
|
extend(TopElementProvider)
|
||||||
extend(BasicTypeProvider)
|
extend(BasicTypeProvider)
|
||||||
extend(AtChildrenCompletionProvider)
|
extend(AtChildrenCompletionProvider)
|
||||||
extend(ComponentElementKeywordProvider)
|
extend(ComponentElementKeywordProvider)
|
||||||
extend(ComponentNameProvider)
|
extend(ComponentNameProvider)
|
||||||
extend(PropertyBindingProvider)
|
extend(PropertyBindingProvider)
|
||||||
extend(InheritsCompletionProvider)
|
extend(InheritsCompletionProvider)
|
||||||
|
extend(ExportElementProvider)
|
||||||
|
extend(SubComponentNameProvider)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun extend(
|
private fun extend(
|
||||||
|
|||||||
@@ -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<V : CompletionParameters> : CompletionProvider<V>() {
|
||||||
|
|
||||||
abstract fun pattern(): ElementPattern<out PsiElement>
|
abstract fun pattern(): ElementPattern<out PsiElement>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ object ComponentElementKeywordProvider : AbstractSlintCompletionProvider<Complet
|
|||||||
"in", "out", "in-out", "callback",
|
"in", "out", "in-out", "callback",
|
||||||
"property", "private", "changed",
|
"property", "private", "changed",
|
||||||
"states", "transitions", "function"
|
"states", "transitions", "function"
|
||||||
).map { LookupElementBuilder.create(it) }
|
).map { LookupElementBuilder.create(it).withBoldness(true) }
|
||||||
|
|
||||||
override fun pattern(): ElementPattern<out PsiElement> {
|
override fun pattern(): ElementPattern<out PsiElement> {
|
||||||
return psiElement().withParent(psiElement(Component))
|
return psiElement().withParent(psiElement(Component))
|
||||||
|
|||||||
@@ -1,34 +1,18 @@
|
|||||||
package me.zhouxi.slint.completion.provider
|
package me.zhouxi.slint.completion.provider
|
||||||
|
|
||||||
import com.intellij.codeInsight.completion.*
|
import com.intellij.codeInsight.completion.CompletionParameters
|
||||||
import com.intellij.codeInsight.lookup.LookupElement
|
import com.intellij.codeInsight.completion.CompletionResultSet
|
||||||
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
||||||
import com.intellij.codeInsight.lookup.LookupElementDecorator.withInsertHandler
|
|
||||||
import com.intellij.icons.AllIcons
|
import com.intellij.icons.AllIcons
|
||||||
import com.intellij.openapi.vfs.VfsUtil
|
|
||||||
import com.intellij.patterns.ElementPattern
|
import com.intellij.patterns.ElementPattern
|
||||||
import com.intellij.patterns.PlatformPatterns.psiElement
|
import com.intellij.patterns.PlatformPatterns.psiElement
|
||||||
import com.intellij.patterns.StandardPatterns.or
|
import com.intellij.patterns.StandardPatterns.or
|
||||||
import com.intellij.psi.PsiDocumentManager
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiFile
|
|
||||||
import com.intellij.psi.PsiManager
|
|
||||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
|
||||||
import com.intellij.psi.search.GlobalSearchScope.projectScope
|
|
||||||
import com.intellij.psi.stubs.StubIndex
|
|
||||||
import com.intellij.psi.util.PsiTreeUtil
|
|
||||||
import com.intellij.psi.util.childrenOfType
|
|
||||||
import com.intellij.util.ProcessingContext
|
import com.intellij.util.ProcessingContext
|
||||||
import me.zhouxi.slint.lang.createComma
|
import me.zhouxi.slint.lang.psi.SlintTypes.ExportSpecifier
|
||||||
import me.zhouxi.slint.lang.createImport
|
|
||||||
import me.zhouxi.slint.lang.createImportSpecifier
|
|
||||||
import me.zhouxi.slint.lang.psi.SlintComponent
|
|
||||||
import me.zhouxi.slint.lang.psi.SlintImport
|
|
||||||
import me.zhouxi.slint.lang.psi.SlintInheritDeclaration
|
|
||||||
import me.zhouxi.slint.lang.psi.SlintTypes.Component
|
|
||||||
import me.zhouxi.slint.lang.psi.SlintTypes.InheritDeclaration
|
import me.zhouxi.slint.lang.psi.SlintTypes.InheritDeclaration
|
||||||
import me.zhouxi.slint.lang.psi.extension.importNames
|
import me.zhouxi.slint.lang.psi.extension.relativePathOf
|
||||||
import me.zhouxi.slint.lang.psi.stubs.index.StubIndexKeys
|
import me.zhouxi.slint.lang.psi.stubs.index.searchComponent
|
||||||
|
|
||||||
object ComponentNameProvider : AbstractSlintCompletionProvider<CompletionParameters>() {
|
object ComponentNameProvider : AbstractSlintCompletionProvider<CompletionParameters>() {
|
||||||
override fun addCompletions(
|
override fun addCompletions(
|
||||||
@@ -37,88 +21,21 @@ object ComponentNameProvider : AbstractSlintCompletionProvider<CompletionParamet
|
|||||||
result: CompletionResultSet
|
result: CompletionResultSet
|
||||||
) {
|
) {
|
||||||
val project = parameters.position.project
|
val project = parameters.position.project
|
||||||
val components = arrayListOf<SlintComponent>()
|
val components = searchComponent(project) { result.prefixMatcher.prefixMatches(it) }
|
||||||
StubIndex.getInstance().processAllKeys(StubIndexKeys.Component, project) {
|
|
||||||
if (result.prefixMatcher.prefixMatches(it)) {
|
|
||||||
val elements = StubIndex.getElements(
|
|
||||||
StubIndexKeys.Component,
|
|
||||||
it,
|
|
||||||
project,
|
|
||||||
projectScope(project),
|
|
||||||
SlintComponent::class.java
|
|
||||||
)
|
|
||||||
components.addAll(elements)
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
val lookups = components.map {
|
val lookups = components.map {
|
||||||
val targetFile = it.containingFile.originalFile
|
|
||||||
val currentFile = parameters.position.containingFile.originalFile.virtualFile
|
val currentFile = parameters.position.containingFile.originalFile.virtualFile
|
||||||
val path = VfsUtil.findRelativePath(currentFile, targetFile.virtualFile, '/')
|
LookupElementBuilder.create(it).withTypeText(it.relativePathOf(currentFile)).withIcon(AllIcons.Nodes.Class)
|
||||||
val builder = LookupElementBuilder.create(it).withTypeText(path).withIcon(AllIcons.Nodes.Class)
|
|
||||||
withInsertHandler(builder, ComponentInsertHandler(targetFile, path))
|
|
||||||
}
|
}
|
||||||
result.addAllElements(lookups)
|
result.addAllElements(lookups)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ComponentInsertHandler(
|
|
||||||
private val targetFile: PsiFile,
|
|
||||||
private val path: String?
|
|
||||||
) : InsertHandler<LookupElement> {
|
|
||||||
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
|
||||||
//insert '{}'
|
|
||||||
val caretOffset: Int = context.editor.caretModel.offset
|
|
||||||
val elementAt = context.file.findElementAt(caretOffset)
|
|
||||||
if (elementAt?.prevSibling !is SlintInheritDeclaration) {
|
|
||||||
context.document.insertString(caretOffset, " { }")
|
|
||||||
context.editor.caretModel.moveToOffset(caretOffset + 3)
|
|
||||||
PsiDocumentManager.getInstance(context.project).commitDocument(context.document)
|
|
||||||
}
|
|
||||||
val component = item.psiElement as SlintComponent
|
|
||||||
if (component.containingFile.isEquivalentTo(context.file)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val targetImport = context.file.childrenOfType<SlintImport>().find { import ->
|
|
||||||
val target = import.importElement?.moduleLocation?.reference?.resolve()
|
|
||||||
PsiManager.getInstance(context.project).areElementsEquivalent(target, targetFile)
|
|
||||||
}
|
|
||||||
if (targetImport == null) {
|
|
||||||
//不存在对指定文件的Import,插入
|
|
||||||
val import = createImport(context.project, component.componentName!!.text, path!!)
|
|
||||||
context.file.addBefore(import, context.file.firstChild)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
//如果导入的Name里面包含了这个ComponentName
|
|
||||||
if (targetImport.importNames().any { it.textMatches(component.componentName!!) }) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
//引入的文件存在,但是没有导入对应组件
|
|
||||||
val importElement = targetImport.importElement!!
|
|
||||||
val specifier = createImportSpecifier(context.project, component.componentName!!.text)
|
|
||||||
val last = importElement.importSpecifierList.lastOrNull()
|
|
||||||
//不存在前置节点
|
|
||||||
if (last == null) {
|
|
||||||
importElement.addAfter(specifier, importElement.childrenOfType<LeafPsiElement>()[0])
|
|
||||||
PsiDocumentManager.getInstance(context.project).commitDocument(context.document)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val element = PsiTreeUtil.nextVisibleLeaf(last)
|
|
||||||
if (!element!!.textMatches(",")) {
|
|
||||||
val comma = importElement.addAfter(createComma(context.project), last)
|
|
||||||
importElement.addAfter(specifier, comma)
|
|
||||||
PsiDocumentManager.getInstance(context.project).commitDocument(context.document)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
PsiDocumentManager.getInstance(context.project).commitDocument(context.document)
|
|
||||||
importElement.addAfter(specifier, element)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun pattern(): ElementPattern<out PsiElement> {
|
override fun pattern(): ElementPattern<out PsiElement> {
|
||||||
return or(
|
return psiElement()
|
||||||
psiElement().withParent(psiElement(Component)).andNot(AtChildrenCompletionProvider.pattern()),
|
.withSuperParent(
|
||||||
psiElement().withSuperParent(2, psiElement(InheritDeclaration))
|
2, or(
|
||||||
|
psiElement(InheritDeclaration),
|
||||||
|
psiElement(ExportSpecifier)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
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.create
|
||||||
|
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.psi.PsiElement
|
||||||
|
import com.intellij.util.ProcessingContext
|
||||||
|
import me.zhouxi.slint.lang.psi.SlintTypes.Component
|
||||||
|
import me.zhouxi.slint.lang.psi.stubs.types.SlintFileElementType
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zhouxi 2024/6/6
|
||||||
|
*/
|
||||||
|
object ExportElementProvider : AbstractSlintCompletionProvider<CompletionParameters>() {
|
||||||
|
|
||||||
|
|
||||||
|
override fun pattern(): ElementPattern<out PsiElement> {
|
||||||
|
return psiElement().withSuperParent(2, psiElement(SlintFileElementType))
|
||||||
|
.andNot(psiElement().withParent(psiElement(Component)))
|
||||||
|
}
|
||||||
|
|
||||||
|
val lookup = arrayOf(
|
||||||
|
create("export "),
|
||||||
|
create("export ").withTailText(" {... }").withInsertHandler(MyInsertHandler())
|
||||||
|
).map { it.withBoldness(true) }
|
||||||
|
|
||||||
|
override fun addCompletions(
|
||||||
|
parameters: CompletionParameters,
|
||||||
|
context: ProcessingContext,
|
||||||
|
result: CompletionResultSet
|
||||||
|
) {
|
||||||
|
result.addAllElements(lookup)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class MyInsertHandler : InsertHandler<LookupElement> {
|
||||||
|
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
||||||
|
val manager = TemplateManager.getInstance(context.project)
|
||||||
|
val template = manager.createTemplate("", "", "{ \$Name$ }").apply {
|
||||||
|
isToReformat = 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);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package me.zhouxi.slint.completion.provider
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zhouxi 2024/6/6
|
||||||
|
*/
|
||||||
@@ -15,7 +15,7 @@ import me.zhouxi.slint.lang.psi.SlintTypes
|
|||||||
object InheritsCompletionProvider : AbstractSlintCompletionProvider<CompletionParameters>() {
|
object InheritsCompletionProvider : AbstractSlintCompletionProvider<CompletionParameters>() {
|
||||||
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.ComponentName)))
|
.afterLeaf(PlatformPatterns.psiElement().withParent(PlatformPatterns.psiElement(SlintTypes.IDENTIFIER)))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addCompletions(
|
override fun addCompletions(
|
||||||
|
|||||||
@@ -0,0 +1,109 @@
|
|||||||
|
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.icons.AllIcons
|
||||||
|
import com.intellij.patterns.ElementPattern
|
||||||
|
import com.intellij.patterns.PlatformPatterns.psiElement
|
||||||
|
import com.intellij.patterns.StandardPatterns.or
|
||||||
|
import com.intellij.psi.PsiDocumentManager
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.PsiFile
|
||||||
|
import com.intellij.psi.PsiManager
|
||||||
|
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
|
import com.intellij.psi.util.childrenOfType
|
||||||
|
import com.intellij.util.ProcessingContext
|
||||||
|
import me.zhouxi.slint.lang.createComma
|
||||||
|
import me.zhouxi.slint.lang.createImport
|
||||||
|
import me.zhouxi.slint.lang.createImportSpecifier
|
||||||
|
import me.zhouxi.slint.lang.psi.SlintComponent
|
||||||
|
import me.zhouxi.slint.lang.psi.SlintImport
|
||||||
|
import me.zhouxi.slint.lang.psi.SlintTypes.Component
|
||||||
|
import me.zhouxi.slint.lang.psi.SlintTypes.SubComponent
|
||||||
|
import me.zhouxi.slint.lang.psi.extension.importNames
|
||||||
|
import me.zhouxi.slint.lang.psi.extension.relativePathOf
|
||||||
|
import me.zhouxi.slint.lang.psi.stubs.index.searchComponent
|
||||||
|
|
||||||
|
object SubComponentNameProvider
|
||||||
|
: AbstractSlintCompletionProvider<CompletionParameters>() {
|
||||||
|
override fun addCompletions(
|
||||||
|
parameters: CompletionParameters,
|
||||||
|
context: ProcessingContext,
|
||||||
|
result: CompletionResultSet
|
||||||
|
) {
|
||||||
|
val project = parameters.position.project
|
||||||
|
val components = searchComponent(project) { result.prefixMatcher.prefixMatches(it) }
|
||||||
|
val lookups = components.map {
|
||||||
|
val targetFile = it.containingFile.originalFile
|
||||||
|
val path = it.relativePathOf(parameters.position) ?: targetFile.name
|
||||||
|
LookupElementBuilder.create(it)
|
||||||
|
.withInsertHandler(ImportComponentInsertHandler(targetFile, path))
|
||||||
|
.withTypeText(path)
|
||||||
|
.withIcon(AllIcons.Nodes.Class)
|
||||||
|
}
|
||||||
|
result.addAllElements(lookups)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ImportComponentInsertHandler(
|
||||||
|
private val targetFile: PsiFile,
|
||||||
|
private val path: String
|
||||||
|
) : InsertHandler<LookupElement> {
|
||||||
|
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
||||||
|
//insert '{}'
|
||||||
|
val caretOffset: Int = context.editor.caretModel.offset
|
||||||
|
context.document.insertString(caretOffset, " { }")
|
||||||
|
context.editor.caretModel.moveToOffset(caretOffset + 3)
|
||||||
|
PsiDocumentManager.getInstance(context.project).commitDocument(context.document)
|
||||||
|
val component = item.psiElement as SlintComponent
|
||||||
|
if (component.containingFile.isEquivalentTo(context.file)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val targetImport = context.file.childrenOfType<SlintImport>().find { import ->
|
||||||
|
val target = import.importElement?.moduleRef?.reference?.resolve()
|
||||||
|
PsiManager.getInstance(context.project).areElementsEquivalent(target, targetFile)
|
||||||
|
}
|
||||||
|
if (targetImport == null) {
|
||||||
|
//不存在对指定文件的Import,插入
|
||||||
|
val import = createImport(context.project, component.identifier!!.text, path)
|
||||||
|
context.file.addBefore(import, context.file.firstChild)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//如果导入的Name里面包含了这个ComponentName
|
||||||
|
if (targetImport.importNames().any { it.textMatches(component.identifier!!) }) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//引入的文件存在,但是没有导入对应组件
|
||||||
|
val importElement = targetImport.importElement!!
|
||||||
|
val specifier = createImportSpecifier(context.project, component.identifier!!.text)
|
||||||
|
val last = importElement.importSpecifierList.lastOrNull()
|
||||||
|
//不存在前置节点
|
||||||
|
if (last == null) {
|
||||||
|
importElement.addAfter(specifier, importElement.childrenOfType<LeafPsiElement>()[0])
|
||||||
|
PsiDocumentManager.getInstance(context.project).commitDocument(context.document)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val element = PsiTreeUtil.nextVisibleLeaf(last)
|
||||||
|
if (!element!!.textMatches(",")) {
|
||||||
|
val comma = importElement.addAfter(createComma(context.project), last)
|
||||||
|
importElement.addAfter(specifier, comma)
|
||||||
|
PsiDocumentManager.getInstance(context.project).commitDocument(context.document)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
PsiDocumentManager.getInstance(context.project).commitDocument(context.document)
|
||||||
|
importElement.addAfter(specifier, element)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun pattern(): ElementPattern<out PsiElement> {
|
||||||
|
return psiElement()
|
||||||
|
.withParent(or(psiElement(Component), psiElement(SubComponent)))
|
||||||
|
.andNot(AtChildrenCompletionProvider.pattern())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -10,7 +10,6 @@ import com.intellij.codeInsight.template.Template
|
|||||||
import com.intellij.codeInsight.template.TemplateEditingAdapter
|
import com.intellij.codeInsight.template.TemplateEditingAdapter
|
||||||
import com.intellij.codeInsight.template.TemplateManager
|
import com.intellij.codeInsight.template.TemplateManager
|
||||||
import com.intellij.codeInsight.template.impl.ConstantNode
|
import com.intellij.codeInsight.template.impl.ConstantNode
|
||||||
import com.intellij.icons.AllIcons
|
|
||||||
import com.intellij.patterns.ElementPattern
|
import com.intellij.patterns.ElementPattern
|
||||||
import com.intellij.patterns.PlatformPatterns.psiElement
|
import com.intellij.patterns.PlatformPatterns.psiElement
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
@@ -18,29 +17,26 @@ 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 TopKeywordProvider : AbstractSlintCompletionProvider<CompletionParameters>() {
|
object TopElementProvider : AbstractSlintCompletionProvider<CompletionParameters>() {
|
||||||
override fun addCompletions(
|
override fun addCompletions(
|
||||||
parameters: CompletionParameters,
|
parameters: CompletionParameters,
|
||||||
context: ProcessingContext,
|
context: ProcessingContext,
|
||||||
result: CompletionResultSet
|
result: CompletionResultSet
|
||||||
) {
|
) {
|
||||||
result.addAllElements(completion)
|
result.addAllElements(completion)
|
||||||
result.addElement(create("component"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val completion = arrayListOf(create("component "), create("struct "), create("enum "))
|
val completion = arrayListOf(
|
||||||
.flatMap {
|
create("component"),
|
||||||
arrayListOf(
|
create("export component"),
|
||||||
it,
|
create("export component").withTailText(" Name {...}").withInsertHandler(MyInsertHandler()),
|
||||||
it.withPresentableText(it.lookupString)
|
create("struct"),
|
||||||
.withTailText("\$Name$ {...}")
|
create("export struct"),
|
||||||
.withInsertHandler(MyInsertHandler()),
|
create("export struct").withTailText(" Name {...}").withInsertHandler(MyInsertHandler()),
|
||||||
create("export ${it.lookupString}"),
|
create("enum"),
|
||||||
create("export ${it.lookupString}")
|
create("export enum"),
|
||||||
.withTailText("\$Name$ {...}")
|
create("export enum").withTailText(" Name {...}").withInsertHandler(MyInsertHandler()),
|
||||||
.withInsertHandler(MyInsertHandler()),
|
).map { it.withBoldness(true) }
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
override fun pattern(): ElementPattern<out PsiElement> {
|
override fun pattern(): ElementPattern<out PsiElement> {
|
||||||
@@ -51,9 +47,10 @@ object TopKeywordProvider : AbstractSlintCompletionProvider<CompletionParameters
|
|||||||
class MyInsertHandler : InsertHandler<LookupElement> {
|
class MyInsertHandler : InsertHandler<LookupElement> {
|
||||||
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
||||||
val manager = TemplateManager.getInstance(context.project)
|
val manager = TemplateManager.getInstance(context.project)
|
||||||
val template = manager.createTemplate("", "", " \$Name$ { \n }")
|
val template = manager.createTemplate("", "", " \$Name$ { \n }").apply {
|
||||||
template.isToReformat = true
|
isToReformat = true
|
||||||
template.addVariable("Name", ConstantNode(""), true)
|
addVariable("Name", ConstantNode(""), true)
|
||||||
|
}
|
||||||
manager.startTemplate(context.editor, template, object : TemplateEditingAdapter() {
|
manager.startTemplate(context.editor, template, object : TemplateEditingAdapter() {
|
||||||
override fun templateFinished(template: Template, brokenOff: Boolean) {
|
override fun templateFinished(template: Template, brokenOff: Boolean) {
|
||||||
context.editor.caretModel.moveToOffset(context.tailOffset - 2);
|
context.editor.caretModel.moveToOffset(context.tailOffset - 2);
|
||||||
@@ -8,6 +8,7 @@ import com.intellij.psi.tree.TokenSet
|
|||||||
import me.zhouxi.slint.lang.psi.SlintPsiKeyword
|
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.SlintTypes.*
|
||||||
|
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
|
import me.zhouxi.slint.lang.psi.utils.keywords
|
||||||
@@ -35,6 +36,10 @@ class FormattingBlock(
|
|||||||
if (child.elementType == TokenType.WHITE_SPACE || child.textLength == 0) {
|
if (child.elementType == TokenType.WHITE_SPACE || child.textLength == 0) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if (Comment.contains(child.elementType)) {
|
||||||
|
current.add(FormattingBlock(child, wrap, alignment, myIndent, spacingBuilder))
|
||||||
|
continue
|
||||||
|
}
|
||||||
if (child.firstChildNode == null || leafTokens.contains(child.elementType)) {
|
if (child.firstChildNode == null || leafTokens.contains(child.elementType)) {
|
||||||
current.add(LeafBlock(child, wrap, alignment, Indent.getNoneIndent(), spacingBuilder))
|
current.add(LeafBlock(child, wrap, alignment, Indent.getNoneIndent(), spacingBuilder))
|
||||||
continue
|
continue
|
||||||
@@ -53,6 +58,13 @@ class FormattingBlock(
|
|||||||
|
|
||||||
override fun getIndent() = indent
|
override fun getIndent() = indent
|
||||||
|
|
||||||
|
override fun getChildAttributes(newChildIndex: Int): ChildAttributes {
|
||||||
|
if (node.elementType == SlintFileElementType) {
|
||||||
|
return ChildAttributes(Indent.getNoneIndent(), null)
|
||||||
|
}
|
||||||
|
return super.getChildAttributes(newChildIndex)
|
||||||
|
}
|
||||||
|
|
||||||
override fun getSpacing(child1: Block?, child2: Block): Spacing? {
|
override fun getSpacing(child1: Block?, child2: Block): Spacing? {
|
||||||
if (child2 is SyntheticBlock) {
|
if (child2 is SyntheticBlock) {
|
||||||
return Spacing.createSpacing(1, 1, 0, true, 2)
|
return Spacing.createSpacing(1, 1, 0, true, 2)
|
||||||
@@ -65,17 +77,17 @@ class FormattingBlock(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private val Comment = TokenSet.create(BlockComment, LineComment)
|
||||||
val leafTokens =
|
val leafTokens =
|
||||||
TokenSet.create(
|
TokenSet.create(
|
||||||
ReferenceIdentifier,
|
ComponentRef,
|
||||||
ComponentName,
|
PropertyRef,
|
||||||
InternalName,
|
FunctionRef,
|
||||||
|
TypeRef,
|
||||||
LocalVariable,
|
LocalVariable,
|
||||||
PropertyName,
|
|
||||||
PropertyModifier,
|
PropertyModifier,
|
||||||
SlintPsiKeyword.ElementType.TYPE
|
SlintPsiKeyword.ElementType.TYPE
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
private val syntheticParentTokens = TokenSet.create(
|
private val syntheticParentTokens = TokenSet.create(
|
||||||
SubComponent,
|
SubComponent,
|
||||||
@@ -83,3 +95,5 @@ class FormattingBlock(
|
|||||||
GlobalSingleton
|
GlobalSingleton
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ import com.intellij.openapi.util.TextRange
|
|||||||
import com.intellij.openapi.util.text.StringUtil
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
import com.intellij.psi.formatter.common.ExtraRangesProvider
|
import com.intellij.psi.formatter.common.ExtraRangesProvider
|
||||||
import com.intellij.psi.formatter.common.NodeIndentRangesCalculator
|
import com.intellij.psi.formatter.common.NodeIndentRangesCalculator
|
||||||
|
import com.intellij.psi.tree.TokenSet
|
||||||
|
import me.zhouxi.slint.lang.psi.SlintTypes.BlockComment
|
||||||
|
import me.zhouxi.slint.lang.psi.SlintTypes.LineComment
|
||||||
|
|
||||||
class LeafBlock(
|
class LeafBlock(
|
||||||
private val treeNode: ASTNode,
|
private val treeNode: ASTNode,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ 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.SlintTypes.*
|
||||||
|
import me.zhouxi.slint.lang.psi.stubs.types.SlintFileElementType
|
||||||
import me.zhouxi.slint.lang.psi.utils.keywords
|
import me.zhouxi.slint.lang.psi.utils.keywords
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,7 +46,7 @@ class SlintFormatterModelBuilder : FormattingModelBuilder {
|
|||||||
.spaces(0)
|
.spaces(0)
|
||||||
.before(Semicolon)
|
.before(Semicolon)
|
||||||
.spacing(0, 0, 0, false, 0)
|
.spacing(0, 0, 0, false, 0)
|
||||||
.after(Semicolon)
|
.after(TokenSet.create(Semicolon))
|
||||||
.lineBreakInCode()
|
.lineBreakInCode()
|
||||||
.after(Colon)
|
.after(Colon)
|
||||||
.spaces(1)
|
.spaces(1)
|
||||||
@@ -57,6 +58,8 @@ class SlintFormatterModelBuilder : FormattingModelBuilder {
|
|||||||
.spaces(1)
|
.spaces(1)
|
||||||
.after(RAngle)
|
.after(RAngle)
|
||||||
.spaces(1)
|
.spaces(1)
|
||||||
|
.afterInside(TokenSet.ANY, SlintFileElementType)
|
||||||
|
.lineBreakInCode()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,10 +39,11 @@ class SyntheticBlock(
|
|||||||
) {
|
) {
|
||||||
return Spacing.createSpacing(1, 1, 0, false, 0)
|
return Spacing.createSpacing(1, 1, 0, false, 0)
|
||||||
}
|
}
|
||||||
return null
|
return Spacing.createSpacing(0, 1, 1, true, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getChildAttributes(newChildIndex: Int) = ChildAttributes(null, subBlocks[0].alignment)
|
override fun getChildAttributes(newChildIndex: Int) =
|
||||||
|
ChildAttributes(Indent.getNormalIndent(), subBlocks[0].alignment)
|
||||||
|
|
||||||
override fun isIncomplete() = false
|
override fun isIncomplete() = false
|
||||||
|
|
||||||
|
|||||||
@@ -24,26 +24,42 @@ class KeywordHighlightAnnotator : Annotator {
|
|||||||
.create()
|
.create()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (element is SlintTypeNameReference && SlintPsiUtils.isInternalType(element)) {
|
if (element is SlintTypeRef && SlintPsiUtils.isInternalType(element)) {
|
||||||
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
|
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
|
||||||
.range(element)
|
.range(element)
|
||||||
.textAttributes(Definitions._KeyWord)
|
.textAttributes(Definitions._KeyWord)
|
||||||
.create()
|
.create()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (element is SlintPropertyName) {
|
if (element is SlintPropertyRef) {
|
||||||
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
|
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
|
||||||
.range(element)
|
.range(element)
|
||||||
.textAttributes(DefaultLanguageHighlighterColors.INSTANCE_FIELD)
|
.textAttributes(DefaultLanguageHighlighterColors.INSTANCE_FIELD)
|
||||||
.create()
|
.create()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (element is SlintProperty) {
|
||||||
|
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
|
||||||
|
.range(element.identifier!!)
|
||||||
|
.textAttributes(DefaultLanguageHighlighterColors.INSTANCE_FIELD)
|
||||||
|
.create()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if (element is SlintPropertyBinding) {
|
if (element is SlintPropertyBinding) {
|
||||||
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
|
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
|
||||||
.range(element.getReferenceIdentifier())
|
.range(element.propertyRef)
|
||||||
.textAttributes(DefaultLanguageHighlighterColors.INSTANCE_FIELD)
|
.textAttributes(DefaultLanguageHighlighterColors.INSTANCE_FIELD)
|
||||||
.create()
|
.create()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if (element is SlintFunctionName || element is SlintFunctionReference) {
|
if (element is SlintFunction) {
|
||||||
|
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
|
||||||
|
.range(element.nameIdentifier!!)
|
||||||
|
.textAttributes(DefaultLanguageHighlighterColors.INSTANCE_METHOD)
|
||||||
|
.create()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (element is SlintFunctionRef) {
|
||||||
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
|
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
|
||||||
.range(element)
|
.range(element)
|
||||||
.textAttributes(DefaultLanguageHighlighterColors.INSTANCE_METHOD)
|
.textAttributes(DefaultLanguageHighlighterColors.INSTANCE_METHOD)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import me.zhouxi.slint.lang.psi.SlintImportSpecifier
|
|||||||
fun createIdentifier(project: Project?, text: String): PsiElement {
|
fun createIdentifier(project: Project?, text: String): PsiElement {
|
||||||
val factory = PsiFileFactory.getInstance(project)
|
val factory = PsiFileFactory.getInstance(project)
|
||||||
val file = factory.createFileFromText("dummy.slint", SlintLanguage.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
|
return file.findChildByClass(SlintComponent::class.java)!!.identifier!!
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createImport(project: Project?, text: String, location: String): PsiElement {
|
fun createImport(project: Project?, text: String, location: String): PsiElement {
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ package me.zhouxi.slint.lang.psi.extension
|
|||||||
|
|
||||||
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
||||||
import com.intellij.icons.AllIcons
|
import com.intellij.icons.AllIcons
|
||||||
|
import com.intellij.openapi.vfs.VfsUtil
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.PsiFile
|
||||||
import com.intellij.psi.util.parentOfType
|
import com.intellij.psi.util.parentOfType
|
||||||
import me.zhouxi.slint.lang.psi.*
|
import me.zhouxi.slint.lang.psi.*
|
||||||
|
|
||||||
@@ -10,16 +13,29 @@ import me.zhouxi.slint.lang.psi.*
|
|||||||
fun SlintComponent.inheritsProperties(): List<SlintProperty> {
|
fun SlintComponent.inheritsProperties(): List<SlintProperty> {
|
||||||
val properties = this.propertyList
|
val properties = this.propertyList
|
||||||
val inherit =
|
val inherit =
|
||||||
this.inheritDeclaration?.referenceIdentifier?.reference?.resolve() as SlintComponent? ?: return properties
|
this.inheritDeclaration?.componentRef?.resolve() ?: return properties
|
||||||
if (inherit == this) {
|
if (inherit == this) {
|
||||||
return properties
|
return properties
|
||||||
}
|
}
|
||||||
return properties + inherit.inheritsProperties()
|
return properties + inherit.inheritsProperties()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun SlintComponent.relativePathOf(element: PsiElement): String? {
|
||||||
|
return relativePathOf(element.containingFile)
|
||||||
|
}
|
||||||
|
|
||||||
fun SlintImport.importNames(): List<SlintReferenceIdentifier> {
|
fun SlintComponent.relativePathOf(psiFile: PsiFile): String? {
|
||||||
return this.importElement?.importSpecifierList?.map { it.referenceIdentifier } ?: emptyList()
|
return psiFile.originalFile.virtualFile?.let { relativePathOf(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun SlintComponent.relativePathOf(file: VirtualFile): String? {
|
||||||
|
val targetFile = this.containingFile.originalFile
|
||||||
|
return VfsUtil.findRelativePath(file, targetFile.virtualFile, '/')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun SlintImport.importNames(): List<SlintComponentRef> {
|
||||||
|
return this.importElement?.importSpecifierList?.map { it.componentRef } ?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,18 +44,26 @@ fun SlintImport.importNames(): List<SlintReferenceIdentifier> {
|
|||||||
*/
|
*/
|
||||||
fun SlintImport.availableNames(): List<PsiElement> {
|
fun SlintImport.availableNames(): List<PsiElement> {
|
||||||
return this.importElement?.importSpecifierList?.map {
|
return this.importElement?.importSpecifierList?.map {
|
||||||
it.importAlias?.internalName ?: it.referenceIdentifier
|
it.importAlias?.identifier ?: it.componentRef
|
||||||
} ?: emptyList()
|
} ?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun SlintSubComponent.resolve(): SlintComponent? {
|
fun SlintSubComponent.resolve(): SlintComponent? {
|
||||||
return this.referenceIdentifier.reference?.resolve() as SlintComponent?
|
return this.componentRef.reference?.resolve() as SlintComponent?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun SlintProperty.toLookupElement(): LookupElementBuilder {
|
fun SlintProperty.toLookupElement(): LookupElementBuilder {
|
||||||
return LookupElementBuilder.create(this)
|
return LookupElementBuilder.create(this)
|
||||||
.withTypeText(this.parentOfType<SlintComponent>()?.componentName?.text)
|
.withTypeText(this.parentOfType<SlintComponent>()?.identifier?.text)
|
||||||
.withIcon(AllIcons.Nodes.Property)
|
.withIcon(AllIcons.Nodes.Property)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun SlintComponentRef?.resolve(): SlintComponent? {
|
||||||
|
return this?.reference?.resolve() as SlintComponent?
|
||||||
|
}
|
||||||
|
|
||||||
|
fun SlintPropertyRef?.resolve(): SlintProperty? {
|
||||||
|
return this?.reference?.resolve() as SlintProperty?
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ 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.SlintNamed
|
||||||
import me.zhouxi.slint.lang.psi.SlintPsiNamedElement
|
import me.zhouxi.slint.lang.psi.SlintPsiNamedElement
|
||||||
|
import me.zhouxi.slint.lang.psi.SlintTypes
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author zhouxi 2024/5/15
|
* @author zhouxi 2024/5/15
|
||||||
@@ -14,7 +15,7 @@ import me.zhouxi.slint.lang.psi.SlintPsiNamedElement
|
|||||||
abstract class SlintPsiNamedElementImpl(node: ASTNode) : SlintPsiElementImpl(node),
|
abstract class SlintPsiNamedElementImpl(node: ASTNode) : SlintPsiElementImpl(node),
|
||||||
SlintPsiNamedElement {
|
SlintPsiNamedElement {
|
||||||
override fun getNameIdentifier(): PsiElement? {
|
override fun getNameIdentifier(): PsiElement? {
|
||||||
return findChildByClass(SlintNamed::class.java) ?: this
|
return findChildByType(SlintTypes.IDENTIFIER) ?: this
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getName(): String? {
|
override fun getName(): String? {
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
package me.zhouxi.slint.lang.psi.stubs.index;
|
|
||||||
|
|
||||||
public class ExportedNameIndex {
|
|
||||||
}
|
|
||||||
@@ -3,12 +3,16 @@ package me.zhouxi.slint.lang.psi.stubs.index
|
|||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope.projectScope
|
||||||
import com.intellij.psi.stubs.StubIndex
|
import com.intellij.psi.stubs.StubIndex
|
||||||
import me.zhouxi.slint.lang.psi.SlintComponent
|
import me.zhouxi.slint.lang.psi.SlintComponent
|
||||||
|
import java.util.function.Predicate
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search Component With Key
|
||||||
|
*/
|
||||||
fun searchComponent(key: String, project: Project, psiFile: PsiFile? = null): Collection<SlintComponent> {
|
fun searchComponent(key: String, project: Project, psiFile: PsiFile? = null): Collection<SlintComponent> {
|
||||||
val scope = psiFile?.let { GlobalSearchScope.fileScope(it) } ?: GlobalSearchScope.projectScope(project)
|
val scope = psiFile?.let { GlobalSearchScope.fileScope(it) } ?: projectScope(project)
|
||||||
return StubIndex.getElements(
|
return StubIndex.getElements(
|
||||||
StubIndexKeys.Component,
|
StubIndexKeys.Component,
|
||||||
key,
|
key,
|
||||||
@@ -16,3 +20,29 @@ fun searchComponent(key: String, project: Project, psiFile: PsiFile? = null): Co
|
|||||||
SlintComponent::class.java
|
SlintComponent::class.java
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search Component With predicate
|
||||||
|
*/
|
||||||
|
fun searchComponent(
|
||||||
|
project: Project,
|
||||||
|
psiFile: PsiFile? = null,
|
||||||
|
predicate: Predicate<String>
|
||||||
|
): Collection<SlintComponent> {
|
||||||
|
val scope = psiFile?.let { GlobalSearchScope.fileScope(it) } ?: projectScope(project)
|
||||||
|
val components = arrayListOf<SlintComponent>()
|
||||||
|
StubIndex.getInstance().processAllKeys(StubIndexKeys.Component, project) {
|
||||||
|
if (predicate.test(it)) {
|
||||||
|
val elements = StubIndex.getElements(
|
||||||
|
StubIndexKeys.Component,
|
||||||
|
it,
|
||||||
|
project,
|
||||||
|
scope,
|
||||||
|
SlintComponent::class.java
|
||||||
|
)
|
||||||
|
components.addAll(elements)
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
return components
|
||||||
|
}
|
||||||
@@ -27,7 +27,7 @@ object SlintComponentElementType :
|
|||||||
return SlintComponentStubImpl(
|
return SlintComponentStubImpl(
|
||||||
parentStub,
|
parentStub,
|
||||||
psi.exportKeyword != null,
|
psi.exportKeyword != null,
|
||||||
psi.componentName!!.text
|
psi.identifier!!.text
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,9 +50,9 @@ 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 exported = tree.getChildren(node).any { it.tokenType == ExportKeyword }
|
||||||
val token = tree.getChildren(node).find { it.tokenType == ComponentName }
|
val token = tree.getChildren(node).find { it.tokenType == IDENTIFIER }
|
||||||
?.let {
|
?.let {
|
||||||
val text = tree.getChildren(it)[0] as LighterASTTokenNode
|
val text = it as LighterASTTokenNode
|
||||||
tree.charTable.intern(text.text)
|
tree.charTable.intern(text.text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,14 +25,14 @@ object SlintImportSpecifierElementType :
|
|||||||
): SlintImportSpecifierStub {
|
): SlintImportSpecifierStub {
|
||||||
val children = tree.getChildren(node);
|
val children = tree.getChildren(node);
|
||||||
val name = run {
|
val name = run {
|
||||||
val nameNode = children.first { it.tokenType == ReferenceIdentifier }
|
val nameNode = children.first { it.tokenType == ComponentRef }
|
||||||
val token = tree.getChildren(nameNode)[0] as LighterASTTokenNode
|
val token = tree.getChildren(nameNode)[0] as LighterASTTokenNode
|
||||||
tree.charTable.intern(token.text).toString()
|
tree.charTable.intern(token.text).toString()
|
||||||
}
|
}
|
||||||
val alias = run {
|
val alias = run {
|
||||||
val aliasNode = children.firstOrNull { it.tokenType == ImportAlias }
|
val aliasNode = children.firstOrNull { it.tokenType == ImportAlias }
|
||||||
aliasNode?.let {
|
aliasNode?.let {
|
||||||
val nameNode = tree.getChildren(aliasNode).firstOrNull { it.tokenType == InternalName }
|
val nameNode = tree.getChildren(aliasNode).firstOrNull { it.tokenType == IDENTIFIER }
|
||||||
val token = nameNode?.let { tree.getChildren(nameNode) }?.firstOrNull() as LighterASTTokenNode?
|
val token = nameNode?.let { tree.getChildren(nameNode) }?.firstOrNull() as LighterASTTokenNode?
|
||||||
token?.let {
|
token?.let {
|
||||||
tree.charTable.intern(it.text).toString()
|
tree.charTable.intern(it.text).toString()
|
||||||
@@ -48,8 +48,8 @@ object SlintImportSpecifierElementType :
|
|||||||
): SlintImportSpecifierStub {
|
): SlintImportSpecifierStub {
|
||||||
return SlintImportSpecifierStubImpl(
|
return SlintImportSpecifierStubImpl(
|
||||||
parentStub,
|
parentStub,
|
||||||
psi.referenceIdentifier.text,
|
psi.componentRef.text,
|
||||||
psi.importAlias?.internalName?.text
|
psi.importAlias?.identifier?.text
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ object SlintPropertyElementType :
|
|||||||
else -> 0
|
else -> 0
|
||||||
}
|
}
|
||||||
} ?: 0
|
} ?: 0
|
||||||
val name = tree.getChildren(children.first { it.tokenType == PropertyName })[0] as LighterASTTokenNode
|
val name = children.first { it.tokenType == IDENTIFIER } as LighterASTTokenNode
|
||||||
return SlintPropertyStubImpl(
|
return SlintPropertyStubImpl(
|
||||||
parentStub,
|
parentStub,
|
||||||
modifierNode.toShort(),
|
modifierNode.toShort(),
|
||||||
@@ -50,7 +50,7 @@ object SlintPropertyElementType :
|
|||||||
val modifier = psi.propertyModifier
|
val modifier = psi.propertyModifier
|
||||||
val isIn = modifier?.inKeyword != null || modifier?.inOutKeyword != null
|
val isIn = modifier?.inKeyword != null || modifier?.inOutKeyword != null
|
||||||
val isOut = modifier?.outKeyword != null || modifier?.inOutKeyword != null
|
val isOut = modifier?.outKeyword != null || modifier?.inOutKeyword != null
|
||||||
val name = psi.propertyName!!.text
|
val name = psi.identifier!!.text
|
||||||
val flag = SlintPropertyStubImpl.pack(isIn, isOut)
|
val flag = SlintPropertyStubImpl.pack(isIn, isOut)
|
||||||
return SlintPropertyStubImpl(parentStub, flag, name)
|
return SlintPropertyStubImpl(parentStub, flag, name)
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/main/kotlin/me/zhouxi/slint/lsp/SlintLspClient.kt
Normal file
16
src/main/kotlin/me/zhouxi/slint/lsp/SlintLspClient.kt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package me.zhouxi.slint.lsp
|
||||||
|
|
||||||
|
import com.intellij.platform.lsp.api.Lsp4jClient
|
||||||
|
import com.intellij.platform.lsp.api.LspServerNotificationsHandler
|
||||||
|
import org.eclipse.lsp4j.jsonrpc.services.JsonNotification
|
||||||
|
|
||||||
|
class SlintLspClient(handler: LspServerNotificationsHandler) : Lsp4jClient(handler) {
|
||||||
|
|
||||||
|
|
||||||
|
@JsonNotification("@slint/showPreview")
|
||||||
|
fun formatDocument() {
|
||||||
|
println("Formatting document")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package me.zhouxi.slint.lsp
|
||||||
|
|
||||||
|
import com.intellij.execution.configurations.GeneralCommandLine
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
import com.intellij.platform.lsp.api.Lsp4jClient
|
||||||
|
import com.intellij.platform.lsp.api.LspServerDescriptor
|
||||||
|
import com.intellij.platform.lsp.api.LspServerNotificationsHandler
|
||||||
|
import me.zhouxi.slint.preview.SlintViewer
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zhouxi 2024/6/3
|
||||||
|
*/
|
||||||
|
class SlintLspServerDescriptor(project: Project) : LspServerDescriptor(project, "slint") {
|
||||||
|
|
||||||
|
override fun isSupportedFile(file: VirtualFile) = file.extension == "slint"
|
||||||
|
|
||||||
|
override fun createCommandLine() = GeneralCommandLine(SlintViewer.executable())
|
||||||
|
|
||||||
|
override fun createLsp4jClient(handler: LspServerNotificationsHandler): Lsp4jClient {
|
||||||
|
return SlintLspClient(handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val lspCompletionSupport = null
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package me.zhouxi.slint.lsp
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
import com.intellij.platform.lsp.api.LspServerSupportProvider
|
||||||
|
import org.jetbrains.annotations.ApiStatus
|
||||||
|
|
||||||
|
class SlintLspServerSupportProvider : LspServerSupportProvider {
|
||||||
|
override fun fileOpened(
|
||||||
|
project: Project,
|
||||||
|
file: VirtualFile,
|
||||||
|
serverStarter: LspServerSupportProvider.LspServerStarter
|
||||||
|
) {
|
||||||
|
if (file.extension == "slint") {
|
||||||
|
serverStarter.ensureServerStarted(SlintLspServerDescriptor(project))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,15 +3,17 @@ package me.zhouxi.slint.preview
|
|||||||
import com.intellij.execution.lineMarker.ExecutorAction
|
import com.intellij.execution.lineMarker.ExecutorAction
|
||||||
import com.intellij.execution.lineMarker.RunLineMarkerContributor
|
import com.intellij.execution.lineMarker.RunLineMarkerContributor
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.util.elementType
|
||||||
import me.zhouxi.slint.lang.SlintLanguage
|
import me.zhouxi.slint.lang.SlintLanguage
|
||||||
import me.zhouxi.slint.lang.psi.SlintComponentName
|
import me.zhouxi.slint.lang.psi.SlintComponent
|
||||||
|
import me.zhouxi.slint.lang.psi.SlintTypes
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author zhouxi 2024/5/16
|
* @author zhouxi 2024/5/16
|
||||||
*/
|
*/
|
||||||
class PreviewRunLineMarkerContributor : RunLineMarkerContributor() {
|
class PreviewRunLineMarkerContributor : RunLineMarkerContributor() {
|
||||||
override fun getInfo(element: PsiElement): Info? {
|
override fun getInfo(element: PsiElement): Info? {
|
||||||
if (element.parent is SlintComponentName) {
|
if (element.parent is SlintComponent && element.elementType == SlintTypes.IDENTIFIER) {
|
||||||
return Info(
|
return Info(
|
||||||
SlintLanguage.ICON, null,
|
SlintLanguage.ICON, null,
|
||||||
*ExecutorAction.getActions(1)
|
*ExecutorAction.getActions(1)
|
||||||
|
|||||||
@@ -10,17 +10,17 @@ import java.nio.file.Paths
|
|||||||
object SlintViewer {
|
object SlintViewer {
|
||||||
|
|
||||||
private val executable = if (SystemInfo.isWindows) {
|
private val executable = if (SystemInfo.isWindows) {
|
||||||
"slint-viewer-windows.exe"
|
"slint-lsp-windows.exe"
|
||||||
} else if (SystemInfo.isLinux) {
|
} else if (SystemInfo.isLinux) {
|
||||||
"slint-viewer-linux"
|
"slint-lsp-linux"
|
||||||
} else if (SystemInfo.isMac) {
|
} else if (SystemInfo.isMac) {
|
||||||
"slint-viewer-macos"
|
"slint-lsp-macos"
|
||||||
} else {
|
} else {
|
||||||
throw RuntimeException("Unsupported OS")
|
throw RuntimeException("Unsupported OS")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun executable(): String {
|
fun executable(): String {
|
||||||
return Paths.get(Plugin.Path.toAbsolutePath().toString(), "slint-viewer", executable).toString()
|
return Paths.get(Plugin.Path.toAbsolutePath().toString(), "slint-lsp", executable).toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,31 +16,17 @@ class SlintReferenceContributor : PsiReferenceContributor() {
|
|||||||
override fun registerReferenceProviders(registrar: PsiReferenceRegistrar) {
|
override fun registerReferenceProviders(registrar: PsiReferenceRegistrar) {
|
||||||
//component Reference
|
//component Reference
|
||||||
registrar.registerReferenceProvider(
|
registrar.registerReferenceProvider(
|
||||||
psiElement(ReferenceIdentifier)
|
psiElement(ComponentRef),
|
||||||
.withParent(
|
|
||||||
or(
|
|
||||||
psiElement(SubComponent),
|
|
||||||
psiElement(Component),
|
|
||||||
psiElement(InheritDeclaration),
|
|
||||||
psiElement(ImportSpecifier)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
ComponentReferenceProvider
|
ComponentReferenceProvider
|
||||||
)
|
)
|
||||||
//moduleLocation Reference
|
//moduleLocation Reference
|
||||||
registrar.registerReferenceProvider(
|
registrar.registerReferenceProvider(
|
||||||
psiElement(ModuleLocation),
|
psiElement(ModuleRef),
|
||||||
ModuleLocationReferenceProvider()
|
ModuleLocationReferenceProvider()
|
||||||
)
|
)
|
||||||
//property binding
|
//property binding
|
||||||
registrar.registerReferenceProvider(
|
registrar.registerReferenceProvider(
|
||||||
psiElement().withParent(
|
psiElement(PropertyRef),
|
||||||
or(
|
|
||||||
psiElement(PropertyBinding),
|
|
||||||
psiElement(Component),
|
|
||||||
psiElement(SubComponent)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
PropertyReferenceProvider
|
PropertyReferenceProvider
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,27 +15,27 @@ import me.zhouxi.slint.lang.psi.stubs.index.searchComponent
|
|||||||
*/
|
*/
|
||||||
object ComponentReferenceProvider : PsiReferenceProvider() {
|
object ComponentReferenceProvider : PsiReferenceProvider() {
|
||||||
override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array<PsiReference> {
|
override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array<PsiReference> {
|
||||||
return arrayOf(SlintComponentNameReference(element as SlintReferenceIdentifier))
|
return arrayOf(SlintComponentNameReference(element as SlintComponentRef))
|
||||||
}
|
}
|
||||||
|
|
||||||
class SlintComponentNameReference(element: SlintReferenceIdentifier) : PsiReferenceBase<PsiElement?>(element) {
|
class SlintComponentNameReference(element: SlintComponentRef) : PsiReferenceBase<PsiElement?>(element) {
|
||||||
override fun resolve(): PsiElement? {
|
override fun resolve(): PsiElement? {
|
||||||
val file = element.containingFile as SlintFile
|
val file = element.containingFile as SlintFile
|
||||||
|
|
||||||
file.childrenOfType<SlintComponent>()
|
file.childrenOfType<SlintComponent>()
|
||||||
.find { it.componentName?.textMatches(element) == true }
|
.find { it.identifier?.textMatches(element) == true }
|
||||||
?.let { return it }
|
?.let { return it }
|
||||||
val specifier = if (element.parent is SlintImportSpecifier) {
|
val specifier = if (element.parent is SlintImportSpecifier) {
|
||||||
element.parent as SlintImportSpecifier
|
element.parent as SlintImportSpecifier
|
||||||
} else {
|
} else {
|
||||||
file.childrenOfType<SlintImport>()
|
file.childrenOfType<SlintImport>()
|
||||||
.flatMap { it.importElement?.importSpecifierList ?: arrayListOf() }
|
.flatMap { it.importElement?.importSpecifierList ?: arrayListOf() }
|
||||||
.find { (it.importAlias?.internalName ?: it.referenceIdentifier).textMatches(element) }
|
.find { (it.importAlias?.identifier ?: it.componentRef).textMatches(element) }
|
||||||
?: return null
|
?: return null
|
||||||
}
|
}
|
||||||
|
|
||||||
val componentName = specifier.referenceIdentifier.text
|
val componentName = specifier.componentRef.text
|
||||||
val location = specifier.parentOfType<SlintImportElement>()?.moduleLocation ?: return null
|
val location = specifier.parentOfType<SlintImportElement>()?.moduleRef ?: return null
|
||||||
val targetFile = location.reference?.resolve()?.containingFile ?: return null
|
val targetFile = location.reference?.resolve()?.containingFile ?: return null
|
||||||
val components = searchComponent(componentName, element.project, targetFile)
|
val components = searchComponent(componentName, element.project, targetFile)
|
||||||
return components.firstOrNull()
|
return components.firstOrNull()
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import com.intellij.openapi.util.TextRange
|
|||||||
import com.intellij.openapi.vfs.VfsUtil
|
import com.intellij.openapi.vfs.VfsUtil
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import com.intellij.util.ProcessingContext
|
import com.intellij.util.ProcessingContext
|
||||||
import me.zhouxi.slint.lang.psi.SlintModuleLocation
|
import me.zhouxi.slint.lang.psi.SlintModuleRef
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author zhouxi 2024/5/17
|
* @author zhouxi 2024/5/17
|
||||||
@@ -16,7 +16,7 @@ class ModuleLocationReferenceProvider : PsiReferenceProvider() {
|
|||||||
|
|
||||||
class ModuleLocationReference(element: PsiElement) : PsiReferenceBase<PsiElement?>(element) {
|
class ModuleLocationReference(element: PsiElement) : PsiReferenceBase<PsiElement?>(element) {
|
||||||
override fun resolve(): PsiElement? {
|
override fun resolve(): PsiElement? {
|
||||||
val location = element as SlintModuleLocation
|
val location = element as SlintModuleRef
|
||||||
val filenameText = location.stringLiteral.text
|
val filenameText = location.stringLiteral.text
|
||||||
if (filenameText.length < 3) return null
|
if (filenameText.length < 3) return null
|
||||||
val directory = element.containingFile.originalFile.virtualFile?.parent ?: return null
|
val directory = element.containingFile.originalFile.virtualFile?.parent ?: return null
|
||||||
@@ -29,6 +29,7 @@ class ModuleLocationReferenceProvider : PsiReferenceProvider() {
|
|||||||
override fun calculateDefaultRangeInElement(): TextRange {
|
override fun calculateDefaultRangeInElement(): TextRange {
|
||||||
return TextRange(1, element.textLength - 1)
|
return TextRange(1, element.textLength - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun bindToElement(element: PsiElement): PsiElement {
|
override fun bindToElement(element: PsiElement): PsiElement {
|
||||||
return element
|
return element
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import com.intellij.util.ProcessingContext
|
|||||||
import me.zhouxi.slint.lang.psi.SlintComponent
|
import me.zhouxi.slint.lang.psi.SlintComponent
|
||||||
import me.zhouxi.slint.lang.psi.SlintSubComponent
|
import me.zhouxi.slint.lang.psi.SlintSubComponent
|
||||||
import me.zhouxi.slint.lang.psi.extension.inheritsProperties
|
import me.zhouxi.slint.lang.psi.extension.inheritsProperties
|
||||||
|
import me.zhouxi.slint.lang.psi.extension.resolve
|
||||||
|
|
||||||
object PropertyReferenceProvider : PsiReferenceProvider() {
|
object PropertyReferenceProvider : PsiReferenceProvider() {
|
||||||
override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array<PsiReference> {
|
override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array<PsiReference> {
|
||||||
@@ -19,11 +20,11 @@ object PropertyReferenceProvider : PsiReferenceProvider() {
|
|||||||
override fun resolve(): PsiElement? {
|
override fun resolve(): PsiElement? {
|
||||||
val subComponent = element.parentOfType<SlintSubComponent>()
|
val subComponent = element.parentOfType<SlintSubComponent>()
|
||||||
if (subComponent != null) {
|
if (subComponent != null) {
|
||||||
val component = subComponent.referenceIdentifier.reference?.resolve() as SlintComponent? ?: return null
|
val component = subComponent.resolve() ?: return null
|
||||||
return component.inheritsProperties().find { it.propertyName?.textMatches(element) == true }
|
return component.inheritsProperties().find { it.identifier?.textMatches(element) == true }
|
||||||
}
|
}
|
||||||
val component = element.parentOfType<SlintComponent>() ?: return null
|
val component = element.parentOfType<SlintComponent>() ?: return null
|
||||||
return component.inheritsProperties().find { it.propertyName?.textMatches(element) == true }
|
return component.inheritsProperties().find { it.identifier?.textMatches(element) == true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,9 @@
|
|||||||
<depends>com.intellij.modules.platform</depends>
|
<depends>com.intellij.modules.platform</depends>
|
||||||
|
|
||||||
<extensions defaultExtensionNs="com.intellij">
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
|
|
||||||
|
<platform.lsp.serverSupportProvider implementation="me.zhouxi.slint.lsp.SlintLspServerSupportProvider"/>
|
||||||
|
|
||||||
<typedHandler implementation="me.zhouxi.slint.completion.SlintCompletionAutoPopupHandler"
|
<typedHandler implementation="me.zhouxi.slint.completion.SlintCompletionAutoPopupHandler"
|
||||||
id="completionAutoPopup"
|
id="completionAutoPopup"
|
||||||
order="first"/>
|
order="first"/>
|
||||||
@@ -29,7 +32,7 @@
|
|||||||
<lang.braceMatcher language="Slint"
|
<lang.braceMatcher language="Slint"
|
||||||
implementationClass="me.zhouxi.slint.brace.SlintPairedBraceMatcher"/>
|
implementationClass="me.zhouxi.slint.brace.SlintPairedBraceMatcher"/>
|
||||||
|
|
||||||
<lang.elementManipulator forClass="me.zhouxi.slint.lang.psi.SlintPsiReferencedIdentifier"
|
<lang.elementManipulator forClass="me.zhouxi.slint.lang.psi.SlintPsiRefIdentifier"
|
||||||
implementationClass="me.zhouxi.slint.reference.SlintElementNameManipulator"/>
|
implementationClass="me.zhouxi.slint.reference.SlintElementNameManipulator"/>
|
||||||
|
|
||||||
<completion.contributor language="Slint"
|
<completion.contributor language="Slint"
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import com.intellij.lexer.FlexAdapter;
|
import com.intellij.lexer.FlexAdapter;
|
||||||
import com.intellij.lexer.Lexer;
|
import com.intellij.lexer.Lexer;
|
||||||
import com.intellij.testFramework.LexerTestCase;
|
import com.intellij.testFramework.LexerTestCase;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import me.zhouxi.slint.lang.lexer.SlintLexer;
|
import me.zhouxi.slint.lang.lexer.SlintLexer;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
@@ -16,7 +15,6 @@ import java.util.concurrent.TimeUnit;
|
|||||||
/**
|
/**
|
||||||
* @author zhouxi 2024/4/30
|
* @author zhouxi 2024/4/30
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
|
||||||
public class LexerTest extends LexerTestCase {
|
public class LexerTest extends LexerTestCase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -44,12 +42,12 @@ public class LexerTest extends LexerTestCase {
|
|||||||
public Stopwatch stopwatch = new Stopwatch() {
|
public Stopwatch stopwatch = new Stopwatch() {
|
||||||
@Override
|
@Override
|
||||||
protected void succeeded(long nanos, Description description) {
|
protected void succeeded(long nanos, Description description) {
|
||||||
log.info("{} succeeded, time taken: {} ms", description.getMethodName(), TimeUnit.NANOSECONDS.toMillis(nanos));
|
// log.info("{} succeeded, time taken: {} ms", description.getMethodName(), TimeUnit.NANOSECONDS.toMillis(nanos));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void failed(long nanos, Throwable e, Description description) {
|
protected void failed(long nanos, Throwable e, Description description) {
|
||||||
log.info("{} failed, time taken: {} ms", description.getMethodName(), TimeUnit.NANOSECONDS.toMillis(nanos));
|
// log.info("{} failed, time taken: {} ms", description.getMethodName(), TimeUnit.NANOSECONDS.toMillis(nanos));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,12 +22,12 @@ public class ParserTest extends ParsingTestCase {
|
|||||||
|
|
||||||
public void test() throws IOException {
|
public void test() throws IOException {
|
||||||
final var path = Paths.get("src/test/resources/slint/main.slint");
|
final var path = Paths.get("src/test/resources/slint/main.slint");
|
||||||
var source = Files.readString(path);
|
var source = """
|
||||||
StopWatch started = StopWatch.createStarted();
|
component App{
|
||||||
for (int i = 0; i < 50000; i++) {
|
aaa;
|
||||||
|
property name;
|
||||||
|
}
|
||||||
|
""";
|
||||||
doCodeTest(source);
|
doCodeTest(source);
|
||||||
}
|
}
|
||||||
started.stop();
|
|
||||||
System.out.println(started.getNanoTime()/50000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user