diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/Scanners.scala | 3 | ||||
-rw-r--r-- | src/library/scala/Function.scala | 118 | ||||
-rw-r--r-- | test/files/neg/implicits.check | 8 | ||||
-rwxr-xr-x | test/files/neg/implicits.scala | 22 | ||||
-rw-r--r-- | test/files/pos/bug851.scala | 28 |
5 files changed, 179 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index 8004976cf5..d612148cfc 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -289,7 +289,10 @@ trait Scanners requires SyntaxAnalyzer { in.next if (in.ch == '\"') { in.next + val saved = in.lineStartPos getMultiLineStringLit + if (in.lineStartPos != saved) // ignore linestarts within a mulit-line string + in.lastLineStartPos = saved } else { token = STRINGLIT name = nme.EMPTY diff --git a/src/library/scala/Function.scala b/src/library/scala/Function.scala new file mode 100644 index 0000000000..7e6e29b0f0 --- /dev/null +++ b/src/library/scala/Function.scala @@ -0,0 +1,118 @@ +package scala + +/** A module defining utility methods for higher-order functional programming. + */ +object Function extends Application { + + /** Given a sequence of functions f_1, ..., f_n, return the + * function `f_1 andThen ... andThen f_n'. + * @param fs The given sequence of functions + */ + def chain[a](fs: Seq[a => a]): a => a = { x => (x /: fs) ((x, f) => f(x)) } + + /** Currying for functions of arity 2. This transforms a function + * of arity 2 into a a unary function returning another unary function. + */ + def curried[a1, a2, b](f: (a1, a2) => b): a1 => a2 => b = { + x1 => x2 => f(x1, x2) + } + + /** Currying for functions of arity 3. + */ + def curried[a1, a2, a3, b](f: (a1, a2, a3) => b): a1 => a2 => a3 => b = { + x1 => x2 => x3 => f(x1, x2, x3) + } + + /** Currying for functions of arity 4. + */ + def curried[a1, a2, a3, a4, b](f: (a1, a2, a3, a4) => b): a1 => a2 => a3 => a4 => b = { + x1 => x2 => x3 => x4 => f(x1, x2, x3, x4) + } + + /** Currying for functions of arity 5. + */ + def curried[a1, a2, a3, a4, a5, b](f: (a1, a2, a3, a4, a5) => b): a1 => a2 => a3 => a4 => a5 => b = { + x1 => x2 => x3 => x4 => x5 => f(x1, x2, x3, x4, x5) + } + + /** Uncurrying for functions of arity 2. This transforms a unary function + * returning another unary function into a function of arity 2. + */ + def uncurried[a1, a2, b](f: a1 => a2 => b): (a1, a2) => b = { + (x1, x2) => f(x1)(x2) + } + + /** Uncurrying for functions of arity 3. + */ + def uncurried[a1, a2, a3, b](f: a1 => a2 => a3 => b): (a1, a2, a3) => b = { + (x1, x2, x3) => f(x1)(x2)(x3) + } + + /** Uncurrying for functions of arity 4. + */ + def uncurried[a1, a2, a3, a4, b](f: a1 => a2 => a3 => a4 => b): (a1, a2, a3, a4) => b = { + (x1, x2, x3, x4) => f(x1)(x2)(x3)(x4) + } + + /** Uncurrying for functions of arity 5. + */ + def uncurried[a1, a2, a3, a4, a5, b](f: a1 => a2 => a3 => a4 => a5 => b): (a1, a2, a3, a4, a5) => b = { + (x1, x2, x3, x4, x5) => f(x1)(x2)(x3)(x4)(x5) + } + + /** Tupling for functions of arity 2. This transforms a function + * of arity 2 into a unary function that takes a pair of arguments. + */ + def tupled[a1, a2, b](f: (a1, a2) => b): Tuple2[a1, a2] => b = { + case Tuple2(x1, x2) => f(x1, x2) + } + + /** Tupling for functions of arity 3. This transforms a function + * of arity 3 into a unary function that takes a triple of arguments. + */ + def tupled[a1, a2, a3, b](f: (a1, a2, a3) => b): Tuple3[a1, a2, a3] => b = { + case Tuple3(x1, x2, x3) => f(x1, x2, x3) + } + + /** Tupling for functions of arity 4. This transforms a function + * of arity 4 into a unary function that takes a 4-tuple of arguments. + */ + def tupled[a1, a2, a3, a4, b](f: (a1, a2, a3, a4) => b): Tuple4[a1, a2, a3, a4] => b = { + case Tuple4(x1, x2, x3, x4) => f(x1, x2, x3, x4) + } + + /** Tupling for functions of arity 5. This transforms a function + * of arity 5 into a unary function that takes a 5-tuple of arguments. + */ + def tupled[a1, a2, a3, a4, a5, b](f: (a1, a2, a3, a4, a5) => b): Tuple5[a1, a2, a3, a4, a5] => b = { + case Tuple5(x1, x2, x3, x4, x5) => f(x1, x2, x3, x4, x5) + } + + /** Un-tupling for functions of arity 2. This transforms a function taking + * a pair of arguments into a binary function which takes each argument separately. + */ + def untupled[a1, a2, b](f: Tuple2[a1, a2] => b): (a1, a2) => b = { + (x1, x2) => f(Tuple2(x1, x2)) + } + + /** Un-tupling for functions of arity 3. This transforms a function taking + * a triple of arguments into a ternary function which takes each argument separately. + */ + def untupled[a1, a2, a3, b](f: Tuple3[a1, a2, a3] => b): (a1, a2, a3) => b = { + (x1, x2, x3) => f(Tuple3(x1, x2, x3)) + } + + /** Un-tupling for functions of arity 4. This transforms a function taking + * a 4-tuple of arguments into a function of arity 4 which takes each argument separately. + */ + def untupled[a1, a2, a3, a4, b](f: Tuple4[a1, a2, a3, a4] => b): (a1, a2, a3, a4) => b = { + (x1, x2, x3, x4) => f(Tuple4(x1, x2, x3, x4)) + } + + /** Un-tupling for functions of arity 5. This transforms a function taking + * a 5-tuple of arguments into a function of arity 5 which takes each argument separately. + */ + def untupled[a1, a2, a3, a4, a5, b](f: Tuple5[a1, a2, a3, a4, a5] => b): (a1, a2, a3, a4, a5) => b = { + (x1, x2, x3, x4, x5) => f(Tuple5(x1, x2, x3, x4, x5)) + } +} diff --git a/test/files/neg/implicits.check b/test/files/neg/implicits.check new file mode 100644 index 0000000000..d1bbd2b3f0 --- /dev/null +++ b/test/files/neg/implicits.check @@ -0,0 +1,8 @@ +implicits.scala:21 error: ambiguous implicit value: + most specific definition is: method pos2int in object Super of type (Pos)scala.Int + yet alternative definition method any2plus in object Sub of type (scala.Any)Sub.Plus + is defined in a subclass. + Both definitions are possible conversion functions from Pos to ?{val +: ?} + f(p+1)
+ ^ +one error found diff --git a/test/files/neg/implicits.scala b/test/files/neg/implicits.scala new file mode 100755 index 0000000000..710ffc94fc --- /dev/null +++ b/test/files/neg/implicits.scala @@ -0,0 +1,22 @@ +class Pos + +class Super + +object Super { + implicit def pos2int(p: Pos): int = 0 +} + +object Sub extends Super { + class Plus(x: Any) { + def +(y: String): String = x.toString + y + } + implicit def any2plus(x: Any): Plus = new Plus(x) +} + +object Test { + import Super._ + import Sub._ + val p = new Pos + def f(x: int): int = x + f(p+1) +} diff --git a/test/files/pos/bug851.scala b/test/files/pos/bug851.scala new file mode 100644 index 0000000000..afe4b79d3c --- /dev/null +++ b/test/files/pos/bug851.scala @@ -0,0 +1,28 @@ +object test { + def ok1: String = { + val x = 1 + """ok1""" + } + def ok2: String = { + val x = "0".length + """ok2""" + } + def ok3: String = { + val x = "0".length + """ok3 + """// + } + def ok4: String = { + val x = "0".length + """ok4 + """ + x + } + def bad: String = { + val x = "0".length + """bad + """ + } + def main(args: Array[String]) { + Console.println(ok1 + ok2 + ok3 + ok4 + bad) + } +} |