summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/jobs/integrate/bootstrap32
-rw-r--r--scripts/repositories-scala-release7
-rwxr-xr-xsrc/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala7
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaSettings.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala10
-rw-r--r--src/compiler/scala/tools/nsc/transform/Delambdafy.scala115
-rw-r--r--src/reflect/scala/reflect/api/Quasiquotes.scala2
-rw-r--r--src/repl/scala/tools/nsc/interpreter/JavapClass.scala34
-rw-r--r--test/files/run/repl-javap-lambdas.scala2
-rw-r--r--test/files/run/t3368-b.check89
-rw-r--r--test/files/run/t3368-b.scala26
-rw-r--r--test/files/run/t3368-c.check85
-rw-r--r--test/files/run/t3368-c.scala26
-rw-r--r--test/files/run/t3368-d.check89
-rw-r--r--test/files/run/t3368-d.scala26
-rw-r--r--test/files/run/t3368.check43
-rw-r--r--test/files/run/t3368.scala8
-rw-r--r--test/files/run/t9268.check5
-rw-r--r--test/files/run/t9268/Java.java12
-rw-r--r--test/files/run/t9268/Test.scala40
20 files changed, 527 insertions, 133 deletions
diff --git a/scripts/jobs/integrate/bootstrap b/scripts/jobs/integrate/bootstrap
index d0a5b452a8..7944ab3fd3 100755
--- a/scripts/jobs/integrate/bootstrap
+++ b/scripts/jobs/integrate/bootstrap
@@ -108,8 +108,22 @@ rm -rf $baseDir/resolutionScratch_
mkdir -p $baseDir/resolutionScratch_
# repo used to publish "locker" scala to (to start the bootstrap)
-privateCred="private-repo"
-privateRepo="http://private-repo.typesafe.com/typesafe/scala-release-temp/"
+releaseTempRepoCred="private-repo"
+releaseTempRepoUrl=${releaseTempRepoUrl-"http://private-repo.typesafe.com/typesafe/scala-release-temp/"}
+
+# Used below in sbtArgs since we use a dedicated repository to share artifcacts between jobs,
+# so we need to configure SBT to use these rather than its default, Maven Central.
+# See http://www.scala-sbt.org/0.13/docs/Proxy-Repositories.html
+sbtRepositoryConfig="$scriptsDir/repositories-scala-release"
+cat > "$sbtRepositoryConfig" << EOF
+[repositories]
+ plugins: http://dl.bintray.com/sbt/sbt-plugin-releases/, [organisation]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
+ private-repo: $releaseTempRepoUrl
+ typesafe-ivy-releases: http://repo.typesafe.com/typesafe/ivy-releases/, [organization]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext], bootOnly
+ sbt-plugin-releases: http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
+ maven-central
+ local
+EOF
##### git
gfxd() {
@@ -158,7 +172,7 @@ function st_stagingRepoClose() {
# the old version (on jenkins, and I don't want to upgrade for risk of breaking other builds) honors -sbt-dir
# the new version of sbt-extras ignores sbt-dir, so we pass it in as -Dsbt.global.base
# need to set sbt-dir to one that has the gpg.sbt plugin config
-sbtArgs="-no-colors -ivy $baseDir/ivy2 -Dsbt.override.build.repos=true -Dsbt.repository.config=$scriptsDir/repositories-scala-release -Dsbt.global.base=$HOME/.sbt/0.13 -sbt-dir $HOME/.sbt/0.13"
+sbtArgs="-no-colors -ivy $baseDir/ivy2 -Dsbt.override.build.repos=true -Dsbt.repository.config=$sbtRepositoryConfig -Dsbt.global.base=$HOME/.sbt/0.13 -sbt-dir $HOME/.sbt/0.13"
sbtBuild() {
echo "### sbtBuild: "$sbtCmd $sbtArgs "${scalaVersionTasks[@]}" "${publishTasks[@]}" "$@"
@@ -457,8 +471,8 @@ bootstrap() {
# in sabbus lingo, the resulting Scala build will be used as starr to build the released Scala compiler
ant -Dmaven.version.number=$SCALA_VER\
-Dremote.snapshot.repository=NOPE\
- -Dremote.release.repository=$privateRepo\
- -Drepository.credentials.id=$privateCred\
+ -Dremote.release.repository=$releaseTempRepoUrl\
+ -Drepository.credentials.id=$releaseTempRepoCred\
-Dscalac.args.optimise=-optimise\
-Ddocs.skip=1\
-Dlocker.skip=1\
@@ -471,7 +485,7 @@ bootstrap() {
# publish to our internal repo (so we can resolve the modules in the scala build below)
# we only need to build the modules necessary to build Scala itself
# since the version of locker and quick are the same
- publishTasks=('set credentials += Credentials(Path.userHome / ".credentials-private-repo")' "set every publishTo := Some(\"private-repo\" at \"$privateRepo\")")
+ publishTasks=('set credentials += Credentials(Path.userHome / ".credentials-private-repo")' "set every publishTo := Some(\"private-repo\" at \"$releaseTempRepoUrl\")")
buildTasks=($publishPrivateTask)
buildModules
@@ -496,14 +510,14 @@ bootstrap() {
# which is fully cross-versioned (for $SCALA_VER, the version we're releasing)
ant -Dstarr.version=$SCALA_VER\
-Dscala.full.version=$SCALA_VER\
- -Dextra.repo.url=$privateRepo\
+ -Dextra.repo.url=$releaseTempRepoUrl\
-Dmaven.version.suffix=$SCALA_VER_SUFFIX\
${updatedModuleVersions[@]} \
-Dupdate.versions=1\
-Dscaladoc.git.commit=$SCALADOC_SOURCE_LINKS_VER\
-Dremote.snapshot.repository=NOPE\
- -Dremote.release.repository=$privateRepo\
- -Drepository.credentials.id=$privateCred\
+ -Dremote.release.repository=$releaseTempRepoUrl\
+ -Drepository.credentials.id=$releaseTempRepoCred\
-Dscalac.args.optimise=-optimise\
$antBuildTask $publishPrivateTask
diff --git a/scripts/repositories-scala-release b/scripts/repositories-scala-release
deleted file mode 100644
index 00538a08ff..0000000000
--- a/scripts/repositories-scala-release
+++ /dev/null
@@ -1,7 +0,0 @@
-[repositories]
- plugins: http://dl.bintray.com/sbt/sbt-plugin-releases/, [organisation]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
- private-repo: http://private-repo.typesafe.com/typesafe/scala-release-temp/
- typesafe-ivy-releases: http://repo.typesafe.com/typesafe/ivy-releases/, [organization]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext], bootOnly
- sbt-plugin-releases: http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
- maven-central
- local \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
index 99399e363f..67241ef639 100755
--- a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
@@ -126,10 +126,9 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) {
def makeTextPat(txt: Tree) = Apply(_scala_xml__Text, List(txt))
def makeText1(txt: Tree) = New(_scala_xml_Text, LL(txt))
def comment(pos: Position, text: String) = atPos(pos)( Comment(const(text)) )
- def charData(pos: Position, txt: String) = atPos(pos) {
- val t = if (isPattern) Apply(_scala_xml(xmlterms._PCData), List(const(txt)))
- else New(_scala_xml(_PCData), LL(const(txt)))
- if (coalescing) t updateAttachment TextAttache(pos, txt) else t
+ def charData(pos: Position, txt: String) = if (coalescing) text(pos, txt) else atPos(pos) {
+ if (isPattern) Apply(_scala_xml(xmlterms._PCData), List(const(txt)))
+ else New(_scala_xml(_PCData), LL(const(txt)))
}
def procInstr(pos: Position, target: String, txt: String) =
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
index f217d21c35..630276e412 100644
--- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
@@ -142,7 +142,7 @@ trait ScalaSettings extends AbsScalaSettings
// XML parsing options
object XxmlSettings extends MultiChoiceEnumeration {
val coalescing = Choice("coalescing", "Convert PCData to Text and coalesce sibling nodes")
- def isCoalescing = Xxml contains coalescing
+ def isCoalescing = (Xxml contains coalescing) || (!isScala212 && !Xxml.isSetByUser)
}
val Xxml = MultiChoiceSetting(
name = "-Xxml",
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 994bcd8359..a59b9d3f48 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -1141,16 +1141,12 @@ abstract class ClassfileParser {
private def innerSymbol(entry: InnerClassEntry): Symbol = {
val name = entry.originalName.toTypeName
val enclosing = entry.enclosing
- def getMember = (
+ val member = (
if (enclosing == clazz) entry.scope lookup name
else lookupMemberAtTyperPhaseIfPossible(enclosing, name)
)
- getMember
- /* There used to be an assertion that this result is not NoSymbol; changing it to an error
- * revealed it had been going off all the time, but has been swallowed by a catch t: Throwable
- * in Repository.scala. Since it has been accomplishing nothing except misleading anyone who
- * thought it wasn't triggering, I removed it entirely.
- */
+ def newStub = enclosing.newStubSymbol(name, s"Unable to locate class corresponding to inner class entry for $name in owner ${entry.outerName}")
+ member.orElse(newStub)
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
index 94e88589f5..2d33b35241 100644
--- a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
+++ b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
@@ -15,13 +15,12 @@ import scala.collection.mutable.LinkedHashMap
* Currently Uncurry is responsible for that transformation.
*
* From a lambda, Delambdafy will create
- * 1) a static forwarder at the top level of the class that contained the lambda
- * 2) a new top level class that
+ * 1) a new top level class that
a) has fields and a constructor taking the captured environment (including possibly the "this"
* reference)
- * b) an apply method that calls the static forwarder
+ * b) an apply method that calls the target method
* c) if needed a bridge method for the apply method
- * 3) an instantiation of the newly created class which replaces the lambda
+ * 2) an instantiation of the newly created class which replaces the lambda
*
* TODO the main work left to be done is to plug into specialization. Primarily that means choosing a
* specialized FunctionN trait instead of the generic FunctionN trait as a parent and creating the
@@ -76,36 +75,25 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
referrers
}
- val accessorMethods = mutable.ArrayBuffer[Tree]()
-
- // the result of the transformFunction method. A class definition for the lambda, an expression
- // insantiating the lambda class, and an accessor method for the lambda class to be able to
- // call the implementation
- case class TransformedFunction(lambdaClassDef: ClassDef, newExpr: Tree, accessorMethod: Tree)
+ // the result of the transformFunction method.
+ sealed abstract class TransformedFunction
+ // A class definition for the lambda, an expression insantiating the lambda class
+ case class DelambdafyAnonClass(lambdaClassDef: ClassDef, newExpr: Tree) extends TransformedFunction
// here's the main entry point of the transform
override def transform(tree: Tree): Tree = tree match {
// the main thing we care about is lambdas
case fun @ Function(_, _) =>
- // a lambda beccomes a new class, an instantiation expression, and an
- // accessor method
- val TransformedFunction(lambdaClassDef, newExpr, accessorMethod) = transformFunction(fun)
- // we'll add accessor methods to the current template later
- accessorMethods += accessorMethod
- val pkg = lambdaClassDef.symbol.owner
-
- // we'll add the lambda class to the package later
- lambdaClassDefs(pkg) = lambdaClassDef :: lambdaClassDefs(pkg)
-
- super.transform(newExpr)
- // when we encounter a template (basically the thing that holds body of a class/trait)
- // we need to updated it to include newly created accessor methods after transforming it
- case Template(_, _, _) =>
- try {
- // during this call accessorMethods will be populated from the Function case
- val Template(parents, self, body) = super.transform(tree)
- Template(parents, self, body ++ accessorMethods)
- } finally accessorMethods.clear()
+ transformFunction(fun) match {
+ case DelambdafyAnonClass(lambdaClassDef, newExpr) =>
+ // a lambda beccomes a new class, an instantiation expression
+ val pkg = lambdaClassDef.symbol.owner
+
+ // we'll add the lambda class to the package later
+ lambdaClassDefs(pkg) = lambdaClassDef :: lambdaClassDefs(pkg)
+
+ super.transform(newExpr)
+ }
case _ => super.transform(tree)
}
@@ -120,8 +108,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
private def optionSymbol(sym: Symbol): Option[Symbol] = if (sym.exists) Some(sym) else None
- // turns a lambda into a new class def, a New expression instantiating that class, and an
- // accessor method fo the body of the lambda
+ // turns a lambda into a new class def, a New expression instantiating that class
private def transformFunction(originalFunction: Function): TransformedFunction = {
val functionTpe = originalFunction.tpe
val targs = functionTpe.typeArgs
@@ -132,46 +119,16 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
// passed into the constructor of the anonymous function class
val captures = FreeVarTraverser.freeVarsOf(originalFunction)
- /**
- * Creates the apply method for the anonymous subclass of FunctionN
- */
- def createAccessorMethod(thisProxy: Symbol, fun: Function): DefDef = {
- val target = targetMethod(fun)
- if (!thisProxy.exists) {
- target setFlag STATIC
- }
- val params = ((optionSymbol(thisProxy) map {proxy:Symbol => ValDef(proxy)}) ++ (target.paramss.flatten map ValDef.apply)).toList
-
- val methSym = oldClass.newMethod(unit.freshTermName(nme.accessor.toString() + "$"), target.pos, FINAL | BRIDGE | SYNTHETIC | PROTECTED | STATIC)
+ val target = targetMethod(originalFunction)
+ target.makeNotPrivate(target.owner)
+ if (!thisReferringMethods.contains(target))
+ target setFlag STATIC
- val paramSyms = params map {param => methSym.newSyntheticValueParam(param.symbol.tpe, param.name) }
-
- params zip paramSyms foreach { case (valdef, sym) => valdef.symbol = sym }
- params foreach (_.symbol.owner = methSym)
-
- val methodType = MethodType(paramSyms, restpe)
- methSym setInfo methodType
-
- oldClass.info.decls enter methSym
-
- val body = localTyper.typed {
- val newTarget = Select(if (thisProxy.exists) gen.mkAttributedRef(paramSyms(0)) else gen.mkAttributedThis(oldClass), target)
- val newParams = paramSyms drop (if (thisProxy.exists) 1 else 0) map Ident
- Apply(newTarget, newParams)
- } setPos fun.pos
- val methDef = DefDef(methSym, List(params), body)
-
- // Have to repack the type to avoid mismatches when existentials
- // appear in the result - see SI-4869.
- // TODO probably don't need packedType
- methDef.tpt setType localTyper.packedType(body, methSym)
- methDef
- }
/**
* Creates the apply method for the anonymous subclass of FunctionN
*/
- def createApplyMethod(newClass: Symbol, fun: Function, accessor: DefDef, thisProxy: Symbol): DefDef = {
+ def createApplyMethod(newClass: Symbol, fun: Function, thisProxy: Symbol): DefDef = {
val methSym = newClass.newMethod(nme.apply, fun.pos, FINAL | SYNTHETIC)
val params = fun.vparams map (_.duplicate)
@@ -187,8 +144,12 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
newClass.info.decls enter methSym
val Apply(_, oldParams) = fun.body
+ val qual = if (thisProxy.exists)
+ Select(gen.mkAttributedThis(newClass), thisProxy)
+ else
+ gen.mkAttributedThis(oldClass) // sort of a lie, EmptyTree.<static method> would be more honest, but the backend chokes on that.
- val body = localTyper typed Apply(Select(gen.mkAttributedThis(oldClass), accessor.symbol), (optionSymbol(thisProxy) map {tp => Select(gen.mkAttributedThis(newClass), tp)}).toList ++ oldParams)
+ val body = localTyper typed Apply(Select(qual, target), oldParams)
body.substituteSymbols(fun.vparams map (_.symbol), params map (_.symbol))
body changeOwner (fun.symbol -> methSym)
@@ -271,18 +232,16 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
// the Optional proxy that will hold a reference to the 'this'
// object used by the lambda, if any. NoSymbol if there is no this proxy
val thisProxy = {
- val target = targetMethod(originalFunction)
- if (thisReferringMethods contains target) {
+ if (target.hasFlag(STATIC))
+ NoSymbol
+ else {
val sym = lambdaClass.newVariable(nme.FAKE_LOCAL_THIS, originalFunction.pos, SYNTHETIC)
- sym.info = oldClass.tpe
- sym
- } else NoSymbol
+ sym.setInfo(oldClass.tpe)
+ }
}
val decapturify = new DeCapturifyTransformer(captureProxies2, unit, oldClass, lambdaClass, originalFunction.symbol.pos, thisProxy)
- val accessorMethod = createAccessorMethod(thisProxy, originalFunction)
-
val decapturedFunction = decapturify.transform(originalFunction).asInstanceOf[Function]
val members = (optionSymbol(thisProxy).toList ++ (captureProxies2 map (_._2))) map {member =>
@@ -294,7 +253,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
val constr = createConstructor(lambdaClass, members)
// apply method with same arguments and return type as original lambda.
- val applyMethodDef = createApplyMethod(lambdaClass, decapturedFunction, accessorMethod, thisProxy)
+ val applyMethodDef = createApplyMethod(lambdaClass, decapturedFunction, thisProxy)
val bridgeMethod = createBridgeMethod(lambdaClass, originalFunction, applyMethodDef)
@@ -312,10 +271,10 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
val body = members ++ List(constr, applyMethodDef) ++ bridgeMethod
// TODO if member fields are private this complains that they're not accessible
- (localTyper.typedPos(decapturedFunction.pos)(ClassDef(lambdaClass, body)).asInstanceOf[ClassDef], thisProxy, accessorMethod)
+ (localTyper.typedPos(decapturedFunction.pos)(ClassDef(lambdaClass, body)).asInstanceOf[ClassDef], thisProxy)
}
- val (anonymousClassDef, thisProxy, accessorMethod) = makeAnonymousClass
+ val (anonymousClassDef, thisProxy) = makeAnonymousClass
pkg.info.decls enter anonymousClassDef.symbol
@@ -327,7 +286,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
val typedNewStat = localTyper.typedPos(originalFunction.pos)(newStat)
- TransformedFunction(anonymousClassDef, typedNewStat, accessorMethod)
+ DelambdafyAnonClass(anonymousClassDef, typedNewStat)
}
/**
diff --git a/src/reflect/scala/reflect/api/Quasiquotes.scala b/src/reflect/scala/reflect/api/Quasiquotes.scala
index eaae05bed5..554b43afaf 100644
--- a/src/reflect/scala/reflect/api/Quasiquotes.scala
+++ b/src/reflect/scala/reflect/api/Quasiquotes.scala
@@ -3,7 +3,7 @@ package api
trait Quasiquotes { self: Universe =>
- /** Implicit class that introduces `q`, `tq`, `cq,` `p` and `fq` string interpolators
+ /** Implicit class that introduces `q`, `tq`, `cq,` `pq` and `fq` string interpolators
* that are also known as quasiquotes. With their help you can easily manipulate
* Scala reflection ASTs.
*
diff --git a/src/repl/scala/tools/nsc/interpreter/JavapClass.scala b/src/repl/scala/tools/nsc/interpreter/JavapClass.scala
index c80b94bf89..1ccade2172 100644
--- a/src/repl/scala/tools/nsc/interpreter/JavapClass.scala
+++ b/src/repl/scala/tools/nsc/interpreter/JavapClass.scala
@@ -8,6 +8,7 @@ package tools.nsc
package interpreter
import java.lang.{ ClassLoader => JavaClassLoader, Iterable => JIterable }
+import scala.tools.asm.Opcodes
import scala.tools.nsc.util.ScalaClassLoader
import java.io.{ ByteArrayInputStream, CharArrayWriter, FileNotFoundException, PrintWriter, StringWriter, Writer }
import java.util.{ Locale }
@@ -758,32 +759,19 @@ object JavapClass {
import scala.tools.asm.ClassReader
import scala.tools.asm.Opcodes.INVOKESTATIC
import scala.tools.asm.tree.{ ClassNode, MethodInsnNode }
- // the accessor methods invoked statically by the apply of the given closure class
- def accesses(s: String): Seq[(String, String)] = {
- val accessor = """accessor\$\d+""".r
+ def callees(s: String): List[(String, String)] = {
loader classReader s withMethods { ms =>
- ms filter (_.name == "apply") flatMap (_.instructions.toArray.collect {
- case i: MethodInsnNode if i.getOpcode == INVOKESTATIC && when(i.name) { case accessor(_*) => true } => (i.owner, i.name)
- })
+ val nonBridgeApplyMethods = ms filter (_.name == "apply") filter (n => (n.access & Opcodes.ACC_BRIDGE) == 0)
+ val instructions = nonBridgeApplyMethods flatMap (_.instructions.toArray)
+ instructions.collect {
+ case i: MethodInsnNode => (i.owner, i.name)
+ }.toList
}
}
- // get the k.$anonfun for the accessor k.m
- def anonOf(k: String, m: String): String = {
- val res =
- loader classReader k withMethods { ms =>
- ms filter (_.name == m) flatMap (_.instructions.toArray.collect {
- case i: MethodInsnNode if i.getOpcode == INVOKESTATIC && i.name.startsWith("$anonfun") => i.name
- })
- }
- assert(res.size == 1)
- res.head
- }
- // the lambdas invoke accessors that call the anonfuns of interest. Filter k on the k#$anonfuns.
- val ack = accesses(lambda)
- assert(ack.size == 1) // There can be only one.
- ack.head match {
- case (k, _) if target.isModule && !(k endsWith "$") => None
- case (k, m) => Some(s"${k}#${anonOf(k, m)}")
+ callees(lambda) match {
+ case (k, _) :: Nil if target.isModule && !(k endsWith "$") => None
+ case (k, m) :: _ => Some(s"${k}#${m}")
+ case _ => None
}
}
/** Translate the supplied targets to patterns for anonfuns.
diff --git a/test/files/run/repl-javap-lambdas.scala b/test/files/run/repl-javap-lambdas.scala
index c503c99d66..76a6ec8450 100644
--- a/test/files/run/repl-javap-lambdas.scala
+++ b/test/files/run/repl-javap-lambdas.scala
@@ -16,7 +16,7 @@ object Test extends JavapTest {
// three anonfuns of Betty#g
override def yah(res: Seq[String]) = {
import PartialFunction.{ cond => when }
- val r = """\s*private static final .* \$anonfun\$\d+\(.*""".r
+ val r = """.*final .* .*\$anonfun\$\d+\(.*""".r
def filtered = res filter (when(_) { case r(_*) => true })
3 == filtered.size
}
diff --git a/test/files/run/t3368-b.check b/test/files/run/t3368-b.check
new file mode 100644
index 0000000000..4cbe98c577
--- /dev/null
+++ b/test/files/run/t3368-b.check
@@ -0,0 +1,89 @@
+[[syntax trees at end of parser]] // newSource1.scala
+package <empty> {
+ abstract trait X extends scala.AnyRef {
+ def $init$() = {
+ ()
+ };
+ def x = {
+ val $buf = new _root_.scala.xml.NodeBuffer();
+ $buf.$amp$plus(new _root_.scala.xml.PCData("hi & bye"));
+ $buf.$amp$plus(new _root_.scala.xml.PCData("red & black"));
+ $buf
+ }
+ };
+ abstract trait Y extends scala.AnyRef {
+ def $init$() = {
+ ()
+ };
+ def y = {
+ {
+ new _root_.scala.xml.Elem(null, "a", _root_.scala.xml.Null, $scope, false, ({
+ val $buf = new _root_.scala.xml.NodeBuffer();
+ $buf.$amp$plus({
+ {
+ new _root_.scala.xml.Elem(null, "b", _root_.scala.xml.Null, $scope, true)
+ }
+ });
+ $buf.$amp$plus(new _root_.scala.xml.Text("start"));
+ $buf.$amp$plus(new _root_.scala.xml.PCData("hi & bye"));
+ $buf.$amp$plus({
+ {
+ new _root_.scala.xml.Elem(null, "c", _root_.scala.xml.Null, $scope, true)
+ }
+ });
+ $buf.$amp$plus(new _root_.scala.xml.Text("world"));
+ $buf.$amp$plus({
+ {
+ new _root_.scala.xml.Elem(null, "d", _root_.scala.xml.Null, $scope, true)
+ }
+ });
+ $buf.$amp$plus(new _root_.scala.xml.Text("stuff"));
+ $buf.$amp$plus(new _root_.scala.xml.PCData("red & black"));
+ $buf
+ }: _*))
+ }
+ }
+ };
+ abstract trait Z extends scala.AnyRef {
+ def $init$() = {
+ ()
+ };
+ def d = new _root_.scala.xml.PCData("hello, world");
+ def e = {
+ val $buf = new _root_.scala.xml.NodeBuffer();
+ $buf.$amp$plus(new _root_.scala.xml.PCData("hello, world"));
+ $buf.$amp$plus(new _root_.scala.xml.PCData("hello, world"));
+ $buf
+ };
+ def f = {
+ {
+ new _root_.scala.xml.Elem(null, "foo", _root_.scala.xml.Null, $scope, false, ({
+ val $buf = new _root_.scala.xml.NodeBuffer();
+ $buf.$amp$plus(new _root_.scala.xml.Text("x"));
+ $buf.$amp$plus(new _root_.scala.xml.PCData("hello, world"));
+ $buf
+ }: _*))
+ }
+ };
+ def g = {
+ {
+ new _root_.scala.xml.Elem(null, "foo", _root_.scala.xml.Null, $scope, false, ({
+ val $buf = new _root_.scala.xml.NodeBuffer();
+ $buf.$amp$plus(new _root_.scala.xml.PCData("hello, world"));
+ $buf
+ }: _*))
+ }
+ };
+ def h = {
+ {
+ new _root_.scala.xml.Elem(null, "foo", _root_.scala.xml.Null, $scope, false, ({
+ val $buf = new _root_.scala.xml.NodeBuffer();
+ $buf.$amp$plus(new _root_.scala.xml.PCData("hello, world"));
+ $buf.$amp$plus(new _root_.scala.xml.PCData("hello, world"));
+ $buf
+ }: _*))
+ }
+ }
+ }
+}
+
diff --git a/test/files/run/t3368-b.scala b/test/files/run/t3368-b.scala
new file mode 100644
index 0000000000..108cb9a5ee
--- /dev/null
+++ b/test/files/run/t3368-b.scala
@@ -0,0 +1,26 @@
+
+import scala.tools.partest.ParserTest
+
+
+object Test extends ParserTest {
+
+ override def code = """
+ trait X {
+ // error: in XML literal: name expected, but char '!' cannot start a name
+ def x = <![CDATA[hi & bye]]> <![CDATA[red & black]]>
+ }
+ trait Y {
+ def y = <a><b/>start<![CDATA[hi & bye]]><c/>world<d/>stuff<![CDATA[red & black]]></a>
+ }
+ trait Z {
+ def d = <![CDATA[hello, world]]>
+ def e = <![CDATA[hello, world]]><![CDATA[hello, world]]> // top level not coalesced
+ def f = <foo>x<![CDATA[hello, world]]></foo> // adjoining text
+ def g = <foo><![CDATA[hello, world]]></foo> // text node when coalescing
+ def h = <foo><![CDATA[hello, world]]><![CDATA[hello, world]]></foo>
+ }
+ """
+
+ // not coalescing
+ override def extraSettings = s"${super.extraSettings} -Xxml:-coalescing"
+}
diff --git a/test/files/run/t3368-c.check b/test/files/run/t3368-c.check
new file mode 100644
index 0000000000..e0c10cc0dd
--- /dev/null
+++ b/test/files/run/t3368-c.check
@@ -0,0 +1,85 @@
+[[syntax trees at end of parser]] // newSource1.scala
+package <empty> {
+ abstract trait X extends scala.AnyRef {
+ def $init$() = {
+ ()
+ };
+ def x = {
+ val $buf = new _root_.scala.xml.NodeBuffer();
+ $buf.$amp$plus(new _root_.scala.xml.Text("hi & bye"));
+ $buf.$amp$plus(new _root_.scala.xml.Text("red & black"));
+ $buf
+ }
+ };
+ abstract trait Y extends scala.AnyRef {
+ def $init$() = {
+ ()
+ };
+ def y = {
+ {
+ new _root_.scala.xml.Elem(null, "a", _root_.scala.xml.Null, $scope, false, ({
+ val $buf = new _root_.scala.xml.NodeBuffer();
+ $buf.$amp$plus({
+ {
+ new _root_.scala.xml.Elem(null, "b", _root_.scala.xml.Null, $scope, true)
+ }
+ });
+ $buf.$amp$plus(new _root_.scala.xml.Text("starthi & bye"));
+ $buf.$amp$plus({
+ {
+ new _root_.scala.xml.Elem(null, "c", _root_.scala.xml.Null, $scope, true)
+ }
+ });
+ $buf.$amp$plus(new _root_.scala.xml.Text("world"));
+ $buf.$amp$plus({
+ {
+ new _root_.scala.xml.Elem(null, "d", _root_.scala.xml.Null, $scope, true)
+ }
+ });
+ $buf.$amp$plus(new _root_.scala.xml.Text("stuffred & black"));
+ $buf
+ }: _*))
+ }
+ }
+ };
+ abstract trait Z extends scala.AnyRef {
+ def $init$() = {
+ ()
+ };
+ def d = new _root_.scala.xml.Text("hello, world");
+ def e = {
+ val $buf = new _root_.scala.xml.NodeBuffer();
+ $buf.$amp$plus(new _root_.scala.xml.Text("hello, world"));
+ $buf.$amp$plus(new _root_.scala.xml.Text("hello, world"));
+ $buf
+ };
+ def f = {
+ {
+ new _root_.scala.xml.Elem(null, "foo", _root_.scala.xml.Null, $scope, false, ({
+ val $buf = new _root_.scala.xml.NodeBuffer();
+ $buf.$amp$plus(new _root_.scala.xml.Text("xhello, world"));
+ $buf
+ }: _*))
+ }
+ };
+ def g = {
+ {
+ new _root_.scala.xml.Elem(null, "foo", _root_.scala.xml.Null, $scope, false, ({
+ val $buf = new _root_.scala.xml.NodeBuffer();
+ $buf.$amp$plus(new _root_.scala.xml.Text("hello, world"));
+ $buf
+ }: _*))
+ }
+ };
+ def h = {
+ {
+ new _root_.scala.xml.Elem(null, "foo", _root_.scala.xml.Null, $scope, false, ({
+ val $buf = new _root_.scala.xml.NodeBuffer();
+ $buf.$amp$plus(new _root_.scala.xml.Text("hello, worldhello, world"));
+ $buf
+ }: _*))
+ }
+ }
+ }
+}
+
diff --git a/test/files/run/t3368-c.scala b/test/files/run/t3368-c.scala
new file mode 100644
index 0000000000..5121794463
--- /dev/null
+++ b/test/files/run/t3368-c.scala
@@ -0,0 +1,26 @@
+
+import scala.tools.partest.ParserTest
+
+
+object Test extends ParserTest {
+
+ override def code = """
+ trait X {
+ // error: in XML literal: name expected, but char '!' cannot start a name
+ def x = <![CDATA[hi & bye]]> <![CDATA[red & black]]>
+ }
+ trait Y {
+ def y = <a><b/>start<![CDATA[hi & bye]]><c/>world<d/>stuff<![CDATA[red & black]]></a>
+ }
+ trait Z {
+ def d = <![CDATA[hello, world]]>
+ def e = <![CDATA[hello, world]]><![CDATA[hello, world]]> // top level not coalesced
+ def f = <foo>x<![CDATA[hello, world]]></foo> // adjoining text
+ def g = <foo><![CDATA[hello, world]]></foo> // text node when coalescing
+ def h = <foo><![CDATA[hello, world]]><![CDATA[hello, world]]></foo>
+ }
+ """
+
+ // default coalescing behavior, whatever that is today.
+ //override def extraSettings = s"${super.extraSettings} -Xxml:coalescing"
+}
diff --git a/test/files/run/t3368-d.check b/test/files/run/t3368-d.check
new file mode 100644
index 0000000000..4cbe98c577
--- /dev/null
+++ b/test/files/run/t3368-d.check
@@ -0,0 +1,89 @@
+[[syntax trees at end of parser]] // newSource1.scala
+package <empty> {
+ abstract trait X extends scala.AnyRef {
+ def $init$() = {
+ ()
+ };
+ def x = {
+ val $buf = new _root_.scala.xml.NodeBuffer();
+ $buf.$amp$plus(new _root_.scala.xml.PCData("hi & bye"));
+ $buf.$amp$plus(new _root_.scala.xml.PCData("red & black"));
+ $buf
+ }
+ };
+ abstract trait Y extends scala.AnyRef {
+ def $init$() = {
+ ()
+ };
+ def y = {
+ {
+ new _root_.scala.xml.Elem(null, "a", _root_.scala.xml.Null, $scope, false, ({
+ val $buf = new _root_.scala.xml.NodeBuffer();
+ $buf.$amp$plus({
+ {
+ new _root_.scala.xml.Elem(null, "b", _root_.scala.xml.Null, $scope, true)
+ }
+ });
+ $buf.$amp$plus(new _root_.scala.xml.Text("start"));
+ $buf.$amp$plus(new _root_.scala.xml.PCData("hi & bye"));
+ $buf.$amp$plus({
+ {
+ new _root_.scala.xml.Elem(null, "c", _root_.scala.xml.Null, $scope, true)
+ }
+ });
+ $buf.$amp$plus(new _root_.scala.xml.Text("world"));
+ $buf.$amp$plus({
+ {
+ new _root_.scala.xml.Elem(null, "d", _root_.scala.xml.Null, $scope, true)
+ }
+ });
+ $buf.$amp$plus(new _root_.scala.xml.Text("stuff"));
+ $buf.$amp$plus(new _root_.scala.xml.PCData("red & black"));
+ $buf
+ }: _*))
+ }
+ }
+ };
+ abstract trait Z extends scala.AnyRef {
+ def $init$() = {
+ ()
+ };
+ def d = new _root_.scala.xml.PCData("hello, world");
+ def e = {
+ val $buf = new _root_.scala.xml.NodeBuffer();
+ $buf.$amp$plus(new _root_.scala.xml.PCData("hello, world"));
+ $buf.$amp$plus(new _root_.scala.xml.PCData("hello, world"));
+ $buf
+ };
+ def f = {
+ {
+ new _root_.scala.xml.Elem(null, "foo", _root_.scala.xml.Null, $scope, false, ({
+ val $buf = new _root_.scala.xml.NodeBuffer();
+ $buf.$amp$plus(new _root_.scala.xml.Text("x"));
+ $buf.$amp$plus(new _root_.scala.xml.PCData("hello, world"));
+ $buf
+ }: _*))
+ }
+ };
+ def g = {
+ {
+ new _root_.scala.xml.Elem(null, "foo", _root_.scala.xml.Null, $scope, false, ({
+ val $buf = new _root_.scala.xml.NodeBuffer();
+ $buf.$amp$plus(new _root_.scala.xml.PCData("hello, world"));
+ $buf
+ }: _*))
+ }
+ };
+ def h = {
+ {
+ new _root_.scala.xml.Elem(null, "foo", _root_.scala.xml.Null, $scope, false, ({
+ val $buf = new _root_.scala.xml.NodeBuffer();
+ $buf.$amp$plus(new _root_.scala.xml.PCData("hello, world"));
+ $buf.$amp$plus(new _root_.scala.xml.PCData("hello, world"));
+ $buf
+ }: _*))
+ }
+ }
+ }
+}
+
diff --git a/test/files/run/t3368-d.scala b/test/files/run/t3368-d.scala
new file mode 100644
index 0000000000..5777c1a81e
--- /dev/null
+++ b/test/files/run/t3368-d.scala
@@ -0,0 +1,26 @@
+
+import scala.tools.partest.ParserTest
+
+
+object Test extends ParserTest {
+
+ override def code = """
+ trait X {
+ // error: in XML literal: name expected, but char '!' cannot start a name
+ def x = <![CDATA[hi & bye]]> <![CDATA[red & black]]>
+ }
+ trait Y {
+ def y = <a><b/>start<![CDATA[hi & bye]]><c/>world<d/>stuff<![CDATA[red & black]]></a>
+ }
+ trait Z {
+ def d = <![CDATA[hello, world]]>
+ def e = <![CDATA[hello, world]]><![CDATA[hello, world]]> // top level not coalesced
+ def f = <foo>x<![CDATA[hello, world]]></foo> // adjoining text
+ def g = <foo><![CDATA[hello, world]]></foo> // text node when coalescing
+ def h = <foo><![CDATA[hello, world]]><![CDATA[hello, world]]></foo>
+ }
+ """
+
+ // default under 2.12 is not coalescing
+ override def extraSettings = s"${super.extraSettings} -Xsource:212"
+}
diff --git a/test/files/run/t3368.check b/test/files/run/t3368.check
index 1d9dd677f6..e0c10cc0dd 100644
--- a/test/files/run/t3368.check
+++ b/test/files/run/t3368.check
@@ -6,8 +6,8 @@ package <empty> {
};
def x = {
val $buf = new _root_.scala.xml.NodeBuffer();
- $buf.$amp$plus(new _root_.scala.xml.PCData("hi & bye"));
- $buf.$amp$plus(new _root_.scala.xml.PCData("red & black"));
+ $buf.$amp$plus(new _root_.scala.xml.Text("hi & bye"));
+ $buf.$amp$plus(new _root_.scala.xml.Text("red & black"));
$buf
}
};
@@ -41,6 +41,45 @@ package <empty> {
}: _*))
}
}
+ };
+ abstract trait Z extends scala.AnyRef {
+ def $init$() = {
+ ()
+ };
+ def d = new _root_.scala.xml.Text("hello, world");
+ def e = {
+ val $buf = new _root_.scala.xml.NodeBuffer();
+ $buf.$amp$plus(new _root_.scala.xml.Text("hello, world"));
+ $buf.$amp$plus(new _root_.scala.xml.Text("hello, world"));
+ $buf
+ };
+ def f = {
+ {
+ new _root_.scala.xml.Elem(null, "foo", _root_.scala.xml.Null, $scope, false, ({
+ val $buf = new _root_.scala.xml.NodeBuffer();
+ $buf.$amp$plus(new _root_.scala.xml.Text("xhello, world"));
+ $buf
+ }: _*))
+ }
+ };
+ def g = {
+ {
+ new _root_.scala.xml.Elem(null, "foo", _root_.scala.xml.Null, $scope, false, ({
+ val $buf = new _root_.scala.xml.NodeBuffer();
+ $buf.$amp$plus(new _root_.scala.xml.Text("hello, world"));
+ $buf
+ }: _*))
+ }
+ };
+ def h = {
+ {
+ new _root_.scala.xml.Elem(null, "foo", _root_.scala.xml.Null, $scope, false, ({
+ val $buf = new _root_.scala.xml.NodeBuffer();
+ $buf.$amp$plus(new _root_.scala.xml.Text("hello, worldhello, world"));
+ $buf
+ }: _*))
+ }
+ }
}
}
diff --git a/test/files/run/t3368.scala b/test/files/run/t3368.scala
index 15acba5099..284fed0784 100644
--- a/test/files/run/t3368.scala
+++ b/test/files/run/t3368.scala
@@ -12,7 +12,15 @@ object Test extends ParserTest {
trait Y {
def y = <a><b/>start<![CDATA[hi & bye]]><c/>world<d/>stuff<![CDATA[red & black]]></a>
}
+ trait Z {
+ def d = <![CDATA[hello, world]]>
+ def e = <![CDATA[hello, world]]><![CDATA[hello, world]]> // top level not coalesced
+ def f = <foo>x<![CDATA[hello, world]]></foo> // adjoining text
+ def g = <foo><![CDATA[hello, world]]></foo> // text node when coalescing
+ def h = <foo><![CDATA[hello, world]]><![CDATA[hello, world]]></foo>
+ }
"""
+ // coalescing
override def extraSettings = s"${super.extraSettings} -Xxml:coalescing"
}
diff --git a/test/files/run/t9268.check b/test/files/run/t9268.check
new file mode 100644
index 0000000000..90ef940eb3
--- /dev/null
+++ b/test/files/run/t9268.check
@@ -0,0 +1,5 @@
+Compiling Client1
+pos: NoPosition Class Waiter not found - continuing with a stub. WARNING
+Compiling Client2
+pos: NoPosition Class Waiter not found - continuing with a stub. WARNING
+pos: NoPosition Unable to locate class corresponding to inner class entry for Predicate in owner Waiter ERROR
diff --git a/test/files/run/t9268/Java.java b/test/files/run/t9268/Java.java
new file mode 100644
index 0000000000..c9a0bec3ff
--- /dev/null
+++ b/test/files/run/t9268/Java.java
@@ -0,0 +1,12 @@
+public class Java {
+}
+
+class Partial {
+ public <E extends java.lang.Exception> long waitFor(long l, Waiter.Predicate<E> pred) throws E {
+ return 0L;
+ }
+}
+
+class Waiter {
+ interface Predicate<E> {}
+}
diff --git a/test/files/run/t9268/Test.scala b/test/files/run/t9268/Test.scala
new file mode 100644
index 0000000000..813cbe7b60
--- /dev/null
+++ b/test/files/run/t9268/Test.scala
@@ -0,0 +1,40 @@
+import scala.tools.partest._
+import java.io.File
+
+object Test extends StoreReporterDirectTest {
+ def code = ???
+
+ def compileCode(code: String) = {
+ val classpath = List(sys.props("partest.lib"), testOutput.path) mkString sys.props("path.separator")
+ compileString(newCompiler("-cp", classpath, "-d", testOutput.path))(code)
+ }
+
+ def client1 = """
+ class Client1 { def p(p: Partial) = p.toString }
+ """
+
+ def client2 = """
+ class Client2 { def p(p: Partial) = p.waitFor() }
+ """
+
+ def deleteClass(s: String) = {
+ val f = new File(testOutput.path, s + ".class")
+ assert(f.exists)
+ f.delete()
+ }
+
+ def show(): Unit = {
+ deleteClass("Waiter")
+ deleteClass("Waiter$Predicate")
+
+ // Used to crash in Java Generic Signature parsing
+ println("Compiling Client1")
+ compileCode(client1)
+ println(storeReporter.infos.mkString("\n"))
+ storeReporter.reset()
+ println("Compiling Client2")
+ compileCode(client2)
+ println(storeReporter.infos.mkString("\n"))
+ }
+}
+