Skip to content

Commit

Permalink
Create SvelteExpressionBlock
Browse files Browse the repository at this point in the history
  • Loading branch information
tomblachut committed Aug 9, 2020
1 parent b56a40d commit eaa7e87
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package dev.blachut.svelte.lang.format

import com.intellij.formatting.*
import com.intellij.lang.ASTNode
import com.intellij.lang.LanguageFormatting
import com.intellij.lang.javascript.JSTokenTypes
import com.intellij.psi.formatter.common.AbstractBlock
import com.intellij.psi.formatter.xml.AbstractXmlBlock
import com.intellij.psi.formatter.xml.XmlFormattingPolicy
import dev.blachut.svelte.lang.psi.SvelteTagElementTypes
import dev.blachut.svelte.lang.psi.SvelteTokenTypes

class SvelteExpressionBlock(
node: ASTNode,
private val indent: Indent?,
wrap: Wrap?,
private val policy: XmlFormattingPolicy
) :
AbstractBlock(node, wrap, null) {
override fun isLeaf(): Boolean = false

override fun buildChildren(): MutableList<Block> {
val results = ArrayList<Block>(4)

// borrowed from com.intellij.psi.formatter.common.InjectedLanguageBlockBuilder.addInjectedLanguageBlockWrapper
val nodePsi = myNode.psi
val builder = LanguageFormatting.INSTANCE.forContext(nodePsi.language, nodePsi)

var child = myNode.firstChildNode
while (child != null) {
if (child.textLength > 0 && !AbstractXmlBlock.containsWhiteSpacesOnly(child)) {
if (child.elementType === JSTokenTypes.LBRACE) {
val startTag = SvelteTagElementTypes.START_TAGS.contains(myNode.elementType)
val wrap = if (startTag) Wrap.createWrap(WrapType.ALWAYS, true) else null
results.add(SvelteLeafBlock(child, wrap = wrap))
} else if (child.elementType === JSTokenTypes.RBRACE) {
results.add(SvelteLeafBlock(child, indent = Indent.getNoneIndent()))
} else {
if (builder != null) {
val childModel = builder.createModel(child.psi, policy.settings)
results.add(childModel.rootBlock)
} else {
results.add(SvelteLeafBlock(child))
}
}
}

child = child.treeNext
}

return results
}

override fun getSpacing(child1: Block?, child2: Block): Spacing? {
if (child1 !is ASTBlock || child2 !is ASTBlock) {
return null
}

val node1 = child1.node ?: return null
val node2 = child2.node ?: return null

val type1 = node1.elementType
val type2 = node2.elementType

if (SvelteTokenTypes.KEYWORDS.contains(type1) && type2 !== JSTokenTypes.RBRACE) {
return Spacing.createSpacing(1, 1, 0, true, 0)
}

return null
}

override fun getIndent(): Indent? {
return indent
}
}
19 changes: 19 additions & 0 deletions src/main/java/dev/blachut/svelte/lang/format/SvelteLeafBlock.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package dev.blachut.svelte.lang.format

import com.intellij.formatting.Block
import com.intellij.formatting.Indent
import com.intellij.formatting.Spacing
import com.intellij.formatting.Wrap
import com.intellij.lang.ASTNode
import com.intellij.psi.formatter.common.AbstractBlock

class SvelteLeafBlock(node: ASTNode, private val indent: Indent? = null, wrap: Wrap? = null) :
AbstractBlock(node, wrap, null) {
override fun isLeaf(): Boolean = true

override fun buildChildren(): MutableList<Block> = EMPTY

override fun getSpacing(child1: Block?, child2: Block): Spacing? = null

override fun getIndent(): Indent? = indent
}
31 changes: 31 additions & 0 deletions src/main/java/dev/blachut/svelte/lang/format/SvelteXmlBlocks.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.intellij.psi.formatter.xml.XmlFormattingPolicy
import com.intellij.psi.formatter.xml.XmlTagBlock
import com.intellij.psi.impl.source.SourceTreeToPsiMap
import com.intellij.psi.xml.XmlTag
import dev.blachut.svelte.lang.psi.SvelteJSLazyElementTypes.CONTENT_EXPRESSION
import dev.blachut.svelte.lang.psi.blocks.SvelteBlock

class SvelteXmlBlock(
Expand All @@ -20,6 +21,21 @@ class SvelteXmlBlock(
textRange: TextRange?,
preserveSpace: Boolean
) : XmlBlock(node, wrap, alignment, policy, indent, textRange, preserveSpace) {
override fun processChild(
result: MutableList<Block>,
child: ASTNode,
wrap: Wrap?,
alignment: Alignment?,
indent: Indent?
): ASTNode? {
if (child.elementType === CONTENT_EXPRESSION) {
result.add(SvelteExpressionBlock(child, indent, wrap, myXmlFormattingPolicy))
return child
}

return super.processChild(result, child, wrap, alignment, indent)
}

override fun processSimpleChild(
child: ASTNode,
indent: Indent?,
Expand Down Expand Up @@ -94,6 +110,21 @@ abstract class SvelteXmlTagBlockBase(

abstract fun buildSvelteChildren(): List<Block>

override fun processChild(
result: MutableList<Block>,
child: ASTNode,
wrap: Wrap?,
alignment: Alignment?,
indent: Indent?
): ASTNode? {
if (child.elementType === CONTENT_EXPRESSION) {
result.add(SvelteExpressionBlock(child, indent, wrap, myXmlFormattingPolicy))
return child
}

return super.processChild(result, child, wrap, alignment, indent)
}

override fun processSimpleChild(
child: ASTNode,
indent: Indent?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@ class SvelteFormatterTest : FormatterTestCase() {
fun testScriptContents() = doTest()
fun testScriptContentsSingleLine() = doTest()
fun testScriptStyleEmpty() = doTest()

fun testMultilineExpression() = doTest()
fun todoMultilineProp() = doTest()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{@debug {
field: true,
another: "hello"
}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{@debug {
field: true,
another: "hello"
}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Box options={{
gap: 10,
nested: {
option: true
}
}}/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Box options={{
gap: 10,
nested: {
option: true
}
}}/>

0 comments on commit eaa7e87

Please sign in to comment.