summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Haoyi <haoyi@dropbox.com>2014-11-17 00:00:09 -0800
committerLi Haoyi <haoyi@dropbox.com>2014-11-17 00:00:09 -0800
commitf9f749398874120e93eb5bc15eaffbe21462b398 (patch)
tree377dcb880a33e7c12b19dc2f783b2c2b75f91c58
parente070b389be002f955785ad8ccc8cdeb41f34a9f4 (diff)
downloadhands-on-scala-js-f9f749398874120e93eb5bc15eaffbe21462b398.tar.gz
hands-on-scala-js-f9f749398874120e93eb5bc15eaffbe21462b398.tar.bz2
hands-on-scala-js-f9f749398874120e93eb5bc15eaffbe21462b398.zip
Fixed type patterns to use CompoundType to not collide with with `=>` in pattern matches
-rw-r--r--scalatexApi/src/main/scala/scalaparser/ScalaSyntax.scala29
-rw-r--r--scalatexApi/src/test/scala/scalaparser/SyntaxTest.scala76
2 files changed, 92 insertions, 13 deletions
diff --git a/scalatexApi/src/main/scala/scalaparser/ScalaSyntax.scala b/scalatexApi/src/main/scala/scalaparser/ScalaSyntax.scala
index b7501a1..f88a532 100644
--- a/scalatexApi/src/main/scala/scalaparser/ScalaSyntax.scala
+++ b/scalatexApi/src/main/scala/scalaparser/ScalaSyntax.scala
@@ -97,7 +97,9 @@ class ScalaSyntax(val input: ParserInput) extends Parser with Basic with Identif
def ExistentialDcl = rule { "type" ~ TypeDcl | "val" ~ ValDcl }
def InfixType = rule { CompoundType ~ zeroOrMore(Id() ~ optional(Newline) ~ CompoundType) }
- def CompoundType = rule { oneOrMore(AnnotType(false)).separatedBy(WL ~ "with") ~ optional(Refinement) }
+ def CompoundType = rule {
+ oneOrMore(AnnotType(false)).separatedBy(WL ~ "with") ~ optional(Refinement)
+ }
def AnnotType(G: B = t) = rule {
SimpleType(false) ~ zeroOrMore(WL ~ Annotation) ~ W(G)
}
@@ -116,7 +118,7 @@ class ScalaSyntax(val input: ParserInput) extends Parser with Basic with Identif
def Types = rule { oneOrMore(Type).separatedBy(',') }
def Refinement = rule { optional(Newline) ~ '{' ~ oneOrMore(RefineStat).separatedBy(Semi) ~ '}' }
def RefineStat = rule { "type" ~ TypeDef | Dcl | MATCH }
- def TypePat = rule { Type }
+ def TypePat = rule { CompoundType }
def Ascription(G: B = t) = rule { ":" ~ (InfixType | oneOrMore(Annotation) | "_" ~ StrW("*", G)) }
def ParamType = rule { "=>" ~ Type | Type ~ "*" | Type }
@@ -135,7 +137,13 @@ class ScalaSyntax(val input: ParserInput) extends Parser with Basic with Identif
}
def IfCFlow(G: B = t) = rule { "if" ~ '(' ~ Expr() ~ ')' ~ zeroOrMore(Newline) ~ Expr(G) ~ optional(optional(Semi) ~ "else" ~ Expr(G)) }
def WhileCFlow(G: B = t) = rule { "while" ~ '(' ~ Expr() ~ ')' ~ zeroOrMore(Newline) ~ Expr(G) }
- def TryCFlow(G: B = t) = rule { "try" ~ '{' ~ Block ~ StrW("}", G) ~ optional("catch" ~ '{' ~ CaseClauses ~ StrW("}", G)) ~ optional("finally" ~ Expr(G)) }
+ def TryCFlow(G: B = t) = rule {
+ "try" ~ Expr(false) ~
+ optional(WL ~ "catch" ~ Expr(false)) ~
+ optional(WL ~ "finally" ~ Expr(false)) ~
+ W(G)
+ }
+
def DoWhileCFlow(G: B = t) = rule { "do" ~ Expr() ~ optional(Semi) ~ "while" ~ '(' ~ Expr() ~ StrW(")", G) }
def ForCFlow(G: B = t) = rule { "for" ~ ('(' ~ Enumerators ~ ')' | '{' ~ Enumerators ~ '}') ~ zeroOrMore(Newline) ~ optional("yield") ~ Expr(G) }
def PostfixExpr(G: B = t): R0 = rule { InfixExpr(G) ~ optional(Id() ~ optional(Newline)) }
@@ -177,17 +185,17 @@ class ScalaSyntax(val input: ParserInput) extends Parser with Basic with Identif
Expr1(false)
}
def ResultExpr(G: B = t): R0 = rule { (Bindings | optional("implicit") ~ Id() | "_") ~ "=>" ~ Block | Expr1(t) }
- def Enumerators: R0 = rule { Generator ~ zeroOrMore(Semi ~ Enumerator) }
- def Enumerator: R0 = rule { Generator | Guard | Pattern1 ~ '=' ~ Expr() }
- def Generator: R0 = rule { Pattern1 ~ "<-" ~ Expr() ~ optional(Guard) }
+ def Enumerators: R0 = rule { Generator(false) ~ zeroOrMore(Semi ~ Enumerator(false)) ~ WL }
+ def Enumerator(G: B = t): R0 = rule { Generator(G) | Guard(G) | Pattern1 ~ '=' ~ Expr(G) }
+ def Generator(G: B = t): R0 = rule { Pattern1 ~ "<-" ~ Expr(false) ~ optional(WL ~ Guard(false)) ~ W(G) }
def CaseClauses: R0 = rule { oneOrMore(CaseClause) }
- def CaseClause: R0 = rule { "case" ~ Pattern ~ optional(Guard) ~ "=>" ~ Block }
- def Guard: R0 = rule { "if" ~ PostfixExpr() }
+ def CaseClause: R0 = rule { "case" ~ Pattern ~ optional(Guard(true)) ~ "=>" ~ Block }
+ def Guard(G: B = t): R0 = rule { "if" ~ PostfixExpr(G) }
def Pattern: R0 = rule {
- oneOrMore(Pattern1 ).separatedBy('|')
+ oneOrMore(Pattern1).separatedBy('|')
}
def Pattern1: R0 = rule { '_' ~ ':' ~ TypePat | VarId() ~ ':' ~ TypePat | Pattern2 }
- def Pattern2: R0 = rule { VarId() ~ optional("@" ~ Pattern3) | Pattern3 }
+ def Pattern2: R0 = rule { VarId() ~ optional("@" ~ Pattern3) | Pattern3 }
def Pattern3: R0 = rule {
SimplePattern ~ zeroOrMore(Id() ~ SimplePattern)
}
@@ -329,6 +337,7 @@ class ScalaSyntax(val input: ParserInput) extends Parser with Basic with Identif
def PackageObject(G: B = t): R0 = rule { "package" ~ "object" ~ ObjectDef(G) }
def CompilationUnit: Rule1[String] = rule {
capture(
+ WL ~
zeroOrMore(Semi) ~
zeroOrMore("package" ~ QualId(false)).separatedBy(Semi) ~
TopStatSeq ~
diff --git a/scalatexApi/src/test/scala/scalaparser/SyntaxTest.scala b/scalatexApi/src/test/scala/scalaparser/SyntaxTest.scala
index 2c16962..4e69bc2 100644
--- a/scalatexApi/src/test/scala/scalaparser/SyntaxTest.scala
+++ b/scalatexApi/src/test/scala/scalaparser/SyntaxTest.scala
@@ -218,10 +218,69 @@ object SyntaxTest extends TestSuite{
|}
""".stripMargin
)
+ * - check(
+ """/* __ *\
+ |** ________ ___ / / ___ __ ____ Scala.js CLI **
+ |** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL **
+ |** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+ |** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+ |** |/____/ **
+ |\* */
+ |
+ |package scala.scalajs.cli
+ |
+ """.stripMargin
+ )
+ * - check(
+ """
+ |object O{
+ | for {
+ | a <- b
+ | c <- d
+ | } {
+ | 1
+ | }
+ |}
+ """.stripMargin
+ )
+ * - check(
+ """
+ |object O{
+ | val jarFile =
+ | try { 1 }
+ | catch { case _: F => G }
+ |}
+ """.stripMargin
+ )
+ * - check(
+ """
+ |object F{
+ | func{ case _: F => fail }
+ |}
+ """.stripMargin
+ )
+ * - check(
+ """
+ |object SyntaxTest extends TestSuite{
+ | def check[T](input: String) = {
+ | new ScalaSyntax(input).CompilationUnit.run() match{
+ | case Failure(f: ParseError) =>
+ | println(f.position)
+ | println(f.formatExpectedAsString)
+ | println(f.formatTraces)
+ | throw new Exception(f.position + "\t" + f.formatTraces)
+ | case Success(parsed) =>
+ | assert(parsed == input)
+ | }
+ | }
+ |}
+ """.stripMargin
+ )
+
}
- println("Checking")
+ def checkFile(path: String) = check(io.Source.fromFile(path).mkString)
'file{
- def checkFile(path: String) = check(io.Source.fromFile(path).mkString)
+
* - checkFile("scalatexApi/src/main/scala/scalaparser/syntax/Basic.scala")
* - checkFile("scalatexApi/src/main/scala/scalaparser/syntax/Identifiers.scala")
@@ -243,6 +302,17 @@ object SyntaxTest extends TestSuite{
* - checkFile("scalatexPlugin/src/main/scala/scalatex/ScalaTexPlugin.scala")
}
- }
+ 'omg{
+ val root = new java.io.File("../scala-js/")
+ def listFiles(s: java.io.File): Iterator[String] = {
+ val (dirs, files) = s.listFiles().toIterator.partition(_.isDirectory)
+ files.map(_.getPath) ++ dirs.flatMap(listFiles)
+ }
+ for(f <- listFiles(root).filter(_.endsWith(".scala"))){
+ println("CHECKING " + f)
+ checkFile(f)
+ }
+ }
+ }
}