From d229249c8805fdb0eb3536500a6ac8e42e15bd40 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Mon, 3 Nov 2014 20:35:53 -0800 Subject: whitespace/newlines inside Scala blocks work correctly --- .../src/main/scala/scalatex/ScalatexParser.scala | 11 +++- .../src/main/scala/torimatomeru/ScalaSyntax.scala | 2 +- .../src/test/scala/scalatex/ParserTests.scala | 67 ++++++++++++++++++++-- 3 files changed, 73 insertions(+), 7 deletions(-) diff --git a/scalatexApi/src/main/scala/scalatex/ScalatexParser.scala b/scalatexApi/src/main/scala/scalatex/ScalatexParser.scala index dc7bf06..02f1cf5 100644 --- a/scalatexApi/src/main/scala/scalatex/ScalatexParser.scala +++ b/scalatexApi/src/main/scala/scalatex/ScalatexParser.scala @@ -62,11 +62,18 @@ class ScalatexParser(input: ParserInput, indent: Int = 0) extends ScalaSyntax(in Code ~ zeroOrMore(Extension) ~> {Ast.Chain(_, _)} } def Extension: Rule1[Ast.Chain.Sub] = rule { - (capture(('.' ~ Id) ~ optional(TypeArgs)) ~> (Ast.Chain.Prop(_))) | - (capture(!BlockExpr ~ ArgumentExprs) ~> (Ast.Chain.Args(_))) | + (capture(('.' ~ Id) ~ optional(TypeArgs2)) ~> (Ast.Chain.Prop(_))) | + (capture(ArgumentExprs2) ~> (Ast.Chain.Args(_))) | TBlock } + def Ws = Whitespace + // clones of the version in ScalaSyntax, but without tailing whitespace or newlines + def TypeArgs2 = rule { '[' ~ Ws ~ Types ~ ']' } + def ArgumentExprs2 = rule { + '(' ~ Ws ~ (optional(Exprs ~ ',' ~ Ws) ~ PostfixExpr ~ ':' ~ Ws ~ '_' ~ Ws ~ '*' ~ Ws | optional(Exprs)) ~ ')' + } def TBlock = rule{ '{' ~ Body ~ '}' } + def Body = rule{ zeroOrMore( LoneScalaChain | diff --git a/scalatexApi/src/main/scala/torimatomeru/ScalaSyntax.scala b/scalatexApi/src/main/scala/torimatomeru/ScalaSyntax.scala index 5bbd0af..4b94033 100644 --- a/scalatexApi/src/main/scala/torimatomeru/ScalaSyntax.scala +++ b/scalatexApi/src/main/scala/torimatomeru/ScalaSyntax.scala @@ -6,7 +6,7 @@ import org.parboiled2._ class ScalaSyntax(val input: ParserInput) extends Parser with Basic with Identifiers with Literals { - def Whitespace = rule { zeroOrMore(WhitespaceChar | Comment) } + def Whitespace = rule { zeroOrMore(WhitespaceChar | Comment | Newline) } /** * Every token handles space at the end. diff --git a/scalatexApi/src/test/scala/scalatex/ParserTests.scala b/scalatexApi/src/test/scala/scalatex/ParserTests.scala index 0649357..35e7dbc 100644 --- a/scalatexApi/src/test/scala/scalatex/ParserTests.scala +++ b/scalatexApi/src/test/scala/scalatex/ParserTests.scala @@ -4,11 +4,16 @@ package scalatex import org.parboiled2._ import torimatomeru.ScalaSyntax +import scalatex.Ast.Block.Text +import scalatex.Ast.Chain.Args + object ParserTests extends utest.TestSuite{ import Ast._ import utest._ def check[T](input: String, parse: ScalatexParser => scala.util.Try[T], expected: T) = { val parsed = parse(new ScalatexParser(input)) + println(parsed.get) + println(expected) assert(parsed.get == expected) } def tests = TestSuite{ @@ -58,24 +63,78 @@ object ParserTests extends utest.TestSuite{ |@omg | @wtf | @bbq - | @lol - """.stripMargin, + | @lol""".stripMargin, _.Body.run(), Block(Seq( Chain(Code("omg"),Seq(Block(Seq( Chain(Code("wtf"),Seq(Block(Seq( Chain(Code("bbq"),Seq(Block(Seq( Chain(Code("lol"),Seq(Block(Seq( - )))), - Ast.Block.Text("\n ") + )))) )))) )))) )))) )) ) + * - check( + """ + |@omg + | @wtf + |@bbq""".stripMargin, + _.Body.run(), + Block(Seq( + Chain(Code("omg"),Seq(Block( + Seq( + Text("\n "), + Chain(Code("wtf"),Seq())) + ))), + Chain(Code("bbq"), + Seq(Block(Seq())) + ) + )) + ) + * - check( + """ + |@omg("lol", 1, 2) + | @wtf + |bbq""".stripMargin, + _.Body.run(), + Block(Seq( + Chain(Code("omg"),Seq( + Args("""("lol", 1, 2)"""), + Block(Seq( + Text("\n "), + Chain(Code("wtf"),Seq()))) + )), + Text("\n"), + Text("bbq") + )) + ) + * - check( + """ + |@omg("lol", + |1, + | 2 + | ) + | wtf + |bbq""".stripMargin, + _.Body.run(), + Block(Seq( + Chain(Code("omg"),Seq( + Args("(\"lol\",\n1,\n 2\n )"), + Block(Seq( + Text("\n "), Text("wtf") + )) + )), + Text("\n"), + Text("bbq") + )) + ) + } } } + -- cgit v1.2.3