修改bnf
This commit is contained in:
@@ -151,6 +151,7 @@ InheritDeclaration ::= InheritsKeyword ReferenceIdentifier {
|
||||
}
|
||||
ComponentBody ::= '{' ComponentElement* '}'{
|
||||
pin=1
|
||||
recoverWhile=recoverWhileForComponentBody
|
||||
}
|
||||
//组件元素定义
|
||||
private ComponentElement ::=ChildrenPlaceholder| Property | Callback
|
||||
@@ -160,11 +161,7 @@ private ComponentElement ::=ChildrenPlaceholder| Property | Callback
|
||||
| RepetitionElement | SubComponent {
|
||||
recoverWhile(".*")=recoverWhileForComponentBody
|
||||
}
|
||||
private recoverWhileForComponentBody::= !(
|
||||
'property'|'callback'|'changed'
|
||||
|'states'|'transitions'|'pure'
|
||||
|'function'|'public'|'protected'|'for'|'if'|'}'|';'|'@'
|
||||
|GenericIdentifier|PropertyModifier)
|
||||
private recoverWhileForComponentBody::= !('{'|';'|'}'|'@'|GenericIdentifier)
|
||||
|
||||
ChildrenPlaceholder ::= '@' 'children'{
|
||||
pin=1
|
||||
@@ -249,7 +246,8 @@ RepetitionIndex ::= '[' LocalVariable ']'{
|
||||
//--------------------------------SubElementDeclaration Start---------------------------------------------------
|
||||
//子组件结构元素定义
|
||||
SubComponent ::= (PropertyName ':=')? ReferenceIdentifier ComponentBody{
|
||||
pin=2
|
||||
pin=3
|
||||
recoverWhile=recoverWhileForComponentBody
|
||||
}
|
||||
|
||||
//--------------------------------TransitionsDeclaration Start---------------------------------------------------
|
||||
@@ -298,11 +296,11 @@ CodeBlock ::= '{' Statement* '}'{
|
||||
pin=1
|
||||
}
|
||||
private Statement ::= (ReturnStatement|IfElseStatement|ExpressionStatement) ';'?{
|
||||
recoverWhile=recoverWhileStatement
|
||||
recoverWhile=recoverWhileForComponentBody
|
||||
}
|
||||
ExpressionStatement ::= Expression (';' &Statement)?
|
||||
|
||||
private recoverWhileStatement::=!(GenericIdentifier|';'|'}')
|
||||
//private recoverWhileStatement::=!(GenericIdentifier|';'|'}')
|
||||
|
||||
ReturnStatement ::= 'return' (Expression)?{
|
||||
pin=1
|
||||
@@ -331,11 +329,14 @@ private QualifiedNamePropertyBinding::= QualifiedPropertyNameReference ':' Bindi
|
||||
PropertyBinding ::= ReferenceIdentifier ':' BindingStatement{
|
||||
pin=2
|
||||
}
|
||||
private WhileIdentifier::=!('}'|GenericIdentifier)
|
||||
//优先尝试表达式解析 {}属于代码块 {name:xx}属于表达式,那么需要预测后面两个token,第二个token不是':'的情况下才是代码块
|
||||
//所以优先判断对象创建判断,然后进行代码块判断,最后进行表达式
|
||||
//代码块分号可选
|
||||
//表达式需要分号结尾
|
||||
BindingStatement ::=ObjectCreationExpressionWithSem|(CodeBlock ';'?)| ExpressionWithSem
|
||||
BindingStatement ::=ObjectCreationExpressionWithSem|(CodeBlock ';'?)| ExpressionWithSem{
|
||||
recoverWhile=WhileIdentifier
|
||||
}
|
||||
//用于错误的直观化
|
||||
private ObjectCreationExpressionWithSem::=ObjectCreationExpression';'{
|
||||
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.CompletionType
|
||||
import com.intellij.patterns.PlatformPatterns
|
||||
import me.zhouxi.slint.completion.provider.BasicTypeProvider
|
||||
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.completion.provider.*
|
||||
import me.zhouxi.slint.lang.psi.SlintTypes
|
||||
import me.zhouxi.slint.lang.psi.stubs.types.SlintFileElementType
|
||||
|
||||
@@ -38,6 +35,12 @@ class SlintCompletionContributor : CompletionContributor() {
|
||||
PlatformPatterns.psiElement().withAncestor(2, PlatformPatterns.psiElement(SlintTypes.ComponentBody)),
|
||||
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)
|
||||
)
|
||||
),
|
||||
PropertyReferenceProvider()
|
||||
PropertyReferenceProvider
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,18 +10,23 @@ import com.intellij.util.ProcessingContext
|
||||
import me.zhouxi.slint.lang.psi.SlintComponent
|
||||
import me.zhouxi.slint.lang.psi.SlintPropertyBinding
|
||||
import me.zhouxi.slint.lang.psi.SlintSubComponent
|
||||
import me.zhouxi.slint.lang.psi.extension.inheritsProperties
|
||||
import me.zhouxi.slint.lang.psi.utils.searchProperty
|
||||
|
||||
class PropertyReferenceProvider : PsiReferenceProvider() {
|
||||
object PropertyReferenceProvider : PsiReferenceProvider() {
|
||||
override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array<PsiReference> {
|
||||
return arrayOf(PropertyReference(element))
|
||||
}
|
||||
|
||||
class PropertyReference(element: PsiElement) : PsiReferenceBase<PsiElement?>(element) {
|
||||
override fun resolve(): PsiElement? {
|
||||
val binding = element.parentOfType<SlintPropertyBinding>() ?: return null
|
||||
val parent = binding.parentOfTypes(SlintSubComponent::class, SlintComponent::class) ?: return null
|
||||
return searchProperty(parent) { it.propertyName?.textMatches(element) == true }
|
||||
val subComponent = element.parentOfType<SlintSubComponent>()
|
||||
if (subComponent != null) {
|
||||
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