修改bnf
This commit is contained in:
@@ -151,6 +151,7 @@ InheritDeclaration ::= InheritsKeyword ReferenceIdentifier {
|
|||||||
}
|
}
|
||||||
ComponentBody ::= '{' ComponentElement* '}'{
|
ComponentBody ::= '{' ComponentElement* '}'{
|
||||||
pin=1
|
pin=1
|
||||||
|
recoverWhile=recoverWhileForComponentBody
|
||||||
}
|
}
|
||||||
//组件元素定义
|
//组件元素定义
|
||||||
private ComponentElement ::=ChildrenPlaceholder| Property | Callback
|
private ComponentElement ::=ChildrenPlaceholder| Property | Callback
|
||||||
@@ -160,11 +161,7 @@ private ComponentElement ::=ChildrenPlaceholder| Property | Callback
|
|||||||
| RepetitionElement | SubComponent {
|
| RepetitionElement | SubComponent {
|
||||||
recoverWhile(".*")=recoverWhileForComponentBody
|
recoverWhile(".*")=recoverWhileForComponentBody
|
||||||
}
|
}
|
||||||
private recoverWhileForComponentBody::= !(
|
private recoverWhileForComponentBody::= !('{'|';'|'}'|'@'|GenericIdentifier)
|
||||||
'property'|'callback'|'changed'
|
|
||||||
|'states'|'transitions'|'pure'
|
|
||||||
|'function'|'public'|'protected'|'for'|'if'|'}'|';'|'@'
|
|
||||||
|GenericIdentifier|PropertyModifier)
|
|
||||||
|
|
||||||
ChildrenPlaceholder ::= '@' 'children'{
|
ChildrenPlaceholder ::= '@' 'children'{
|
||||||
pin=1
|
pin=1
|
||||||
@@ -249,7 +246,8 @@ RepetitionIndex ::= '[' LocalVariable ']'{
|
|||||||
//--------------------------------SubElementDeclaration Start---------------------------------------------------
|
//--------------------------------SubElementDeclaration Start---------------------------------------------------
|
||||||
//子组件结构元素定义
|
//子组件结构元素定义
|
||||||
SubComponent ::= (PropertyName ':=')? ReferenceIdentifier ComponentBody{
|
SubComponent ::= (PropertyName ':=')? ReferenceIdentifier ComponentBody{
|
||||||
pin=2
|
pin=3
|
||||||
|
recoverWhile=recoverWhileForComponentBody
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------TransitionsDeclaration Start---------------------------------------------------
|
//--------------------------------TransitionsDeclaration Start---------------------------------------------------
|
||||||
@@ -298,11 +296,11 @@ CodeBlock ::= '{' Statement* '}'{
|
|||||||
pin=1
|
pin=1
|
||||||
}
|
}
|
||||||
private Statement ::= (ReturnStatement|IfElseStatement|ExpressionStatement) ';'?{
|
private Statement ::= (ReturnStatement|IfElseStatement|ExpressionStatement) ';'?{
|
||||||
recoverWhile=recoverWhileStatement
|
recoverWhile=recoverWhileForComponentBody
|
||||||
}
|
}
|
||||||
ExpressionStatement ::= Expression (';' &Statement)?
|
ExpressionStatement ::= Expression (';' &Statement)?
|
||||||
|
|
||||||
private recoverWhileStatement::=!(GenericIdentifier|';'|'}')
|
//private recoverWhileStatement::=!(GenericIdentifier|';'|'}')
|
||||||
|
|
||||||
ReturnStatement ::= 'return' (Expression)?{
|
ReturnStatement ::= 'return' (Expression)?{
|
||||||
pin=1
|
pin=1
|
||||||
@@ -331,11 +329,14 @@ private QualifiedNamePropertyBinding::= QualifiedPropertyNameReference ':' Bindi
|
|||||||
PropertyBinding ::= ReferenceIdentifier ':' BindingStatement{
|
PropertyBinding ::= ReferenceIdentifier ':' BindingStatement{
|
||||||
pin=2
|
pin=2
|
||||||
}
|
}
|
||||||
|
private WhileIdentifier::=!('}'|GenericIdentifier)
|
||||||
//优先尝试表达式解析 {}属于代码块 {name:xx}属于表达式,那么需要预测后面两个token,第二个token不是':'的情况下才是代码块
|
//优先尝试表达式解析 {}属于代码块 {name:xx}属于表达式,那么需要预测后面两个token,第二个token不是':'的情况下才是代码块
|
||||||
//所以优先判断对象创建判断,然后进行代码块判断,最后进行表达式
|
//所以优先判断对象创建判断,然后进行代码块判断,最后进行表达式
|
||||||
//代码块分号可选
|
//代码块分号可选
|
||||||
//表达式需要分号结尾
|
//表达式需要分号结尾
|
||||||
BindingStatement ::=ObjectCreationExpressionWithSem|(CodeBlock ';'?)| ExpressionWithSem
|
BindingStatement ::=ObjectCreationExpressionWithSem|(CodeBlock ';'?)| ExpressionWithSem{
|
||||||
|
recoverWhile=WhileIdentifier
|
||||||
|
}
|
||||||
//用于错误的直观化
|
//用于错误的直观化
|
||||||
private ObjectCreationExpressionWithSem::=ObjectCreationExpression';'{
|
private ObjectCreationExpressionWithSem::=ObjectCreationExpression';'{
|
||||||
pin=1
|
pin=1
|
||||||
|
|||||||
68
src/main/grammar/sample.bnf
Normal file
68
src/main/grammar/sample.bnf
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
{
|
||||||
|
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)
|
||||||
@@ -3,10 +3,7 @@ package me.zhouxi.slint.completion
|
|||||||
import com.intellij.codeInsight.completion.CompletionContributor
|
import com.intellij.codeInsight.completion.CompletionContributor
|
||||||
import com.intellij.codeInsight.completion.CompletionType
|
import com.intellij.codeInsight.completion.CompletionType
|
||||||
import com.intellij.patterns.PlatformPatterns
|
import com.intellij.patterns.PlatformPatterns
|
||||||
import me.zhouxi.slint.completion.provider.BasicTypeProvider
|
import me.zhouxi.slint.completion.provider.*
|
||||||
import me.zhouxi.slint.completion.provider.ComponentProvider
|
|
||||||
import me.zhouxi.slint.completion.provider.ElementKeywordProvider
|
|
||||||
import me.zhouxi.slint.completion.provider.TopKeywordProvider
|
|
||||||
import me.zhouxi.slint.lang.psi.SlintTypes
|
import me.zhouxi.slint.lang.psi.SlintTypes
|
||||||
import me.zhouxi.slint.lang.psi.stubs.types.SlintFileElementType
|
import me.zhouxi.slint.lang.psi.stubs.types.SlintFileElementType
|
||||||
|
|
||||||
@@ -38,6 +35,12 @@ class SlintCompletionContributor : CompletionContributor() {
|
|||||||
PlatformPatterns.psiElement().withAncestor(2, PlatformPatterns.psiElement(SlintTypes.ComponentBody)),
|
PlatformPatterns.psiElement().withAncestor(2, PlatformPatterns.psiElement(SlintTypes.ComponentBody)),
|
||||||
ComponentProvider
|
ComponentProvider
|
||||||
)
|
)
|
||||||
|
//propertyBinding
|
||||||
|
extend(
|
||||||
|
CompletionType.BASIC,
|
||||||
|
PlatformPatterns.psiElement().withAncestor(2, PlatformPatterns.psiElement(SlintTypes.ComponentBody)),
|
||||||
|
PropertyBindingProvider
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package me.zhouxi.slint.completion.provider
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.completion.CompletionParameters
|
||||||
|
import com.intellij.codeInsight.completion.CompletionProvider
|
||||||
|
import com.intellij.codeInsight.completion.CompletionResultSet
|
||||||
|
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
||||||
|
import com.intellij.icons.AllIcons
|
||||||
|
import com.intellij.psi.util.parentOfType
|
||||||
|
import com.intellij.util.ProcessingContext
|
||||||
|
import me.zhouxi.slint.lang.psi.SlintComponent
|
||||||
|
import me.zhouxi.slint.lang.psi.SlintSubComponent
|
||||||
|
import me.zhouxi.slint.lang.psi.extension.inheritsProperties
|
||||||
|
|
||||||
|
object PropertyBindingProvider : CompletionProvider<CompletionParameters>() {
|
||||||
|
override fun addCompletions(
|
||||||
|
parameters: CompletionParameters,
|
||||||
|
context: ProcessingContext,
|
||||||
|
result: CompletionResultSet
|
||||||
|
) {
|
||||||
|
val element = parameters.position
|
||||||
|
val subComponent = element.parentOfType<SlintSubComponent>()
|
||||||
|
if (subComponent != null) {
|
||||||
|
val component = subComponent.referenceIdentifier.reference?.resolve() as SlintComponent? ?: return
|
||||||
|
val builders = component.inheritsProperties()
|
||||||
|
.map { LookupElementBuilder.create(it).withTypeText(component.name).withIcon(AllIcons.Nodes.Property) }
|
||||||
|
result.addAllElements(builders)
|
||||||
|
} else {
|
||||||
|
val component = element.parentOfType<SlintComponent>() ?: return
|
||||||
|
val builders = component.inheritsProperties()
|
||||||
|
.map { LookupElementBuilder.create(it).withTypeText(component.name).withIcon(AllIcons.Nodes.Property) }
|
||||||
|
result.addAllElements(builders)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package me.zhouxi.slint.lang.psi.extension
|
||||||
|
|
||||||
|
import me.zhouxi.slint.lang.psi.SlintComponent
|
||||||
|
import me.zhouxi.slint.lang.psi.SlintProperty
|
||||||
|
|
||||||
|
|
||||||
|
fun SlintComponent.inheritsProperties(): List<SlintProperty> {
|
||||||
|
val properties = this.componentBody?.propertyList ?: emptyList()
|
||||||
|
val inherit =
|
||||||
|
this.inheritDeclaration?.referenceIdentifier?.reference?.resolve() as SlintComponent? ?: return properties
|
||||||
|
return properties + inherit.inheritsProperties()
|
||||||
|
}
|
||||||
@@ -41,7 +41,7 @@ class SlintReferenceContributor : PsiReferenceContributor() {
|
|||||||
psiElement(ComponentBody)
|
psiElement(ComponentBody)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
PropertyReferenceProvider()
|
PropertyReferenceProvider
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,18 +10,23 @@ 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.SlintPropertyBinding
|
import me.zhouxi.slint.lang.psi.SlintPropertyBinding
|
||||||
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.utils.searchProperty
|
import me.zhouxi.slint.lang.psi.utils.searchProperty
|
||||||
|
|
||||||
class PropertyReferenceProvider : PsiReferenceProvider() {
|
object PropertyReferenceProvider : PsiReferenceProvider() {
|
||||||
override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array<PsiReference> {
|
override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array<PsiReference> {
|
||||||
return arrayOf(PropertyReference(element))
|
return arrayOf(PropertyReference(element))
|
||||||
}
|
}
|
||||||
|
|
||||||
class PropertyReference(element: PsiElement) : PsiReferenceBase<PsiElement?>(element) {
|
class PropertyReference(element: PsiElement) : PsiReferenceBase<PsiElement?>(element) {
|
||||||
override fun resolve(): PsiElement? {
|
override fun resolve(): PsiElement? {
|
||||||
val binding = element.parentOfType<SlintPropertyBinding>() ?: return null
|
val subComponent = element.parentOfType<SlintSubComponent>()
|
||||||
val parent = binding.parentOfTypes(SlintSubComponent::class, SlintComponent::class) ?: return null
|
if (subComponent != null) {
|
||||||
return searchProperty(parent) { it.propertyName?.textMatches(element) == true }
|
val component = subComponent.referenceIdentifier.reference?.resolve() as SlintComponent? ?: return null
|
||||||
|
return component.inheritsProperties().find { it.propertyName?.textMatches(element) == true }
|
||||||
|
}
|
||||||
|
val component = element.parentOfType<SlintComponent>() ?: return null
|
||||||
|
return component.inheritsProperties().find { it.propertyName?.textMatches(element) == true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user