From 422b06126d3809f4db11dba0988cd21857e1f9de Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 7 Apr 2016 17:49:15 +0200 Subject: [PATCH 01/21] Search implicit arguments in the same context as typing explicit ones For explicit arguments of this(...) constrictor calls we have a special context that hides members of the current class. But for implicit arguments we did not. This led to implicit shadowing errors for scala.collection.immutable.PagedSeq when secondary constructor type parameters were fixed (as done in subsequent commits). --- src/dotty/tools/dotc/typer/Applications.scala | 12 ++++++++---- src/dotty/tools/dotc/typer/Typer.scala | 6 +++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index f3903e5390af..ec2508580bf0 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -531,12 +531,16 @@ trait Applications extends Compatibility { self: Typer => def treeToArg(arg: Tree): Tree = arg } + /** If `app` is a `this(...)` constructor call, the this-call argument context, + * otherwise the current context. + */ + def argCtx(app: untpd.Tree)(implicit ctx: Context): Context = + if (untpd.isSelfConstrCall(app)) ctx.thisCallArgContext else ctx + def typedApply(tree: untpd.Apply, pt: Type)(implicit ctx: Context): Tree = { def realApply(implicit ctx: Context): Tree = track("realApply") { - def argCtx(implicit ctx: Context) = - if (untpd.isSelfConstrCall(tree)) ctx.thisCallArgContext else ctx - var proto = new FunProto(tree.args, IgnoredProto(pt), this)(argCtx) + var proto = new FunProto(tree.args, IgnoredProto(pt), this)(argCtx(tree)) val fun1 = typedExpr(tree.fun, proto) // Warning: The following line is dirty and fragile. We record that auto-tupling was demanded as @@ -554,7 +558,7 @@ trait Applications extends Compatibility { self: Typer => tryEither { implicit ctx => val app = if (proto.argsAreTyped) new ApplyToTyped(tree, fun1, funRef, proto.typedArgs, pt) - else new ApplyToUntyped(tree, fun1, funRef, proto, pt)(argCtx) + else new ApplyToUntyped(tree, fun1, funRef, proto, pt)(argCtx(tree)) val result = app.result convertNewArray(ConstFold(result)) } { (failedVal, failedState) => diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 3b8ada2a8550..fac24e440fe6 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -1518,7 +1518,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit val tvarsToInstantiate = tvarsInParams(tree) wtp.paramTypes.foreach(instantiateSelected(_, tvarsToInstantiate)) val constr = ctx.typerState.constraint - def addImplicitArgs = { + def addImplicitArgs(implicit ctx: Context) = { val errors = new mutable.ListBuffer[() => String] def implicitArgError(msg: => String) = { errors += (() => msg) @@ -1565,9 +1565,9 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit } else adapt(tpd.Apply(tree, args), pt) } - if ((pt eq WildcardType) || original.isEmpty) addImplicitArgs + if ((pt eq WildcardType) || original.isEmpty) addImplicitArgs(argCtx(tree)) else - ctx.typerState.tryWithFallback(addImplicitArgs) { + ctx.typerState.tryWithFallback(addImplicitArgs(argCtx(tree))) { adapt(typed(original, WildcardType), pt, EmptyTree) } case wtp: MethodType if !pt.isInstanceOf[SingletonType] => From 306d422f1e3017731d1f9266f9d445e77ea73105 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 7 Apr 2016 17:56:05 +0200 Subject: [PATCH 02/21] Take type parameters for this(...) constructor calls from prefix Previously, those were inferred from arguments, but this is wrong because we implicitly assume that the type parameters of the constructor and the type parameters of the class are the same. I could not find a test that fails for this. But if you look at the -Xprint:front output of pos/i941.scala, you notice that the inferred argument to the this(...) call was `Nothing` where it should have been `A`. --- src/dotty/tools/dotc/typer/Typer.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index fac24e440fe6..3d36905f29db 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -1677,7 +1677,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit if (pt.isInstanceOf[PolyProto]) tree else { var typeArgs = tree match { - case Select(New(tpt), nme.CONSTRUCTOR) => tpt.tpe.dealias.argTypesLo + case Select(qual, nme.CONSTRUCTOR) => qual.tpe.widenDealias.argTypesLo case _ => Nil } if (typeArgs.isEmpty) typeArgs = constrained(poly, tree)._2 From 03e8c54c0165d129b12bdde29b2482dd1758e418 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 7 Apr 2016 17:58:52 +0200 Subject: [PATCH 03/21] Treat type parameters of secondary constructors as aliases ... of class parameters using the gadt mechanism. Previously they were encoded as aliases by hardcoding alias bounds in the type parameter declaration, but that then leads to weird behavior and failures in unpickling. To make this work, we also need to propagate gadt bounds into the this-call context. Test case in pickling/i1202a.scala. --- src/dotty/tools/dotc/core/Contexts.scala | 11 ++++++++--- src/dotty/tools/dotc/typer/Typer.scala | 19 +++++++++++-------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index a0bb03e505b5..53a4bfe085b2 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -336,13 +336,17 @@ object Contexts { def thisCallArgContext: Context = { assert(owner.isClassConstructor) val constrCtx = outersIterator.dropWhile(_.outer.owner == owner).next - superOrThisCallContext(owner, constrCtx.scope).setTyperState(typerState) + superOrThisCallContext(owner, constrCtx.scope) + .setTyperState(typerState) + .setGadt(gadt) } - /** The super= or this-call context with given owner and locals. */ + /** The super- or this-call context with given owner and locals. */ private def superOrThisCallContext(owner: Symbol, locals: Scope): FreshContext = { var classCtx = outersIterator.dropWhile(!_.isClassDefContext).next - classCtx.outer.fresh.setOwner(owner).setScope(locals).setMode(classCtx.mode | Mode.InSuperCall) + classCtx.outer.fresh.setOwner(owner) + .setScope(locals) + .setMode(classCtx.mode | Mode.InSuperCall) } /** The context of expression `expr` seen as a member of a statement sequence */ @@ -438,6 +442,7 @@ object Contexts { def setImportInfo(importInfo: ImportInfo): this.type = { this.importInfo = importInfo; this } def setRunInfo(runInfo: RunInfo): this.type = { this.runInfo = runInfo; this } def setDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this } + def setGadt(gadt: GADTMap): this.type = { this.gadt = gadt; this } def setTypeComparerFn(tcfn: Context => TypeComparer): this.type = { this.typeComparer = tcfn(this); this } def setSearchHistory(searchHistory: SearchHistory): this.type = { this.searchHistory = searchHistory; this } def setFreshNames(freshNames: FreshNameCreator): this.type = { this.freshNames = freshNames; this } diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 3d36905f29db..10d7516e6c83 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -1022,17 +1022,20 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit val DefDef(name, tparams, vparamss, tpt, _) = ddef completeAnnotations(ddef, sym) val tparams1 = tparams mapconserve (typed(_).asInstanceOf[TypeDef]) - // for secondary constructors we need to use that their type parameters - // are aliases of the class type parameters. See pos/i941.scala - if (sym.isConstructor && !sym.isPrimaryConstructor) - (sym.owner.typeParams, tparams1).zipped.foreach {(tparam, tdef) => - tdef.symbol.info = TypeAlias(tparam.typeRef) - } - val vparamss1 = vparamss nestedMapconserve (typed(_).asInstanceOf[ValDef]) if (sym is Implicit) checkImplicitParamsNotSingletons(vparamss1) val tpt1 = checkSimpleKinded(typedType(tpt)) - val rhs1 = typedExpr(ddef.rhs, tpt1.tpe) + + var rhsCtx = ctx + if (sym.isConstructor && !sym.isPrimaryConstructor && tparams1.nonEmpty) { + // for secondary constructors we need a context that "knows" + // that their type parameters are aliases of the class type parameters. + // See pos/i941.scala + rhsCtx = ctx.fresh.setFreshGADTBounds + (tparams1, sym.owner.typeParams).zipped.foreach ((tdef, tparam) => + rhsCtx.gadt.setBounds(tdef.symbol, TypeAlias(tparam.typeRef))) + } + val rhs1 = typedExpr(ddef.rhs, tpt1.tpe)(rhsCtx) assignType(cpy.DefDef(ddef)(name, tparams1, vparamss1, tpt1, rhs1), sym) //todo: make sure dependent method types do not depend on implicits or by-name params } From e2cdfa3123d311773d34b10f5979181cecd8acf1 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 7 Apr 2016 17:59:44 +0200 Subject: [PATCH 04/21] Augment test case --- tests/pos/i941.scala | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/pos/i941.scala b/tests/pos/i941.scala index 75bf4e4482a7..5a0ef512cc4b 100644 --- a/tests/pos/i941.scala +++ b/tests/pos/i941.scala @@ -7,4 +7,18 @@ object Test { def foo(x: A): Unit = () } + class D[A](x: A) { + + var f = x + + def this(y1: A, y2: A) = { + this(y1) + f = y2 + val g: A = f + foo(y2) + } + + def foo(x: A): Unit = () + + } } From 90f9653d80ef92fb81d3661148d8d51da1e4b568 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 7 Apr 2016 18:01:25 +0200 Subject: [PATCH 05/21] Make first phase of FromTasty not be a Typer `isTyper` is used to enable some error checking and handling, which need not be done when in FromTasty. --- src/dotty/tools/dotc/FromTasty.scala | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/dotty/tools/dotc/FromTasty.scala b/src/dotty/tools/dotc/FromTasty.scala index 8f29c882c8f7..14fd8ad6cf59 100644 --- a/src/dotty/tools/dotc/FromTasty.scala +++ b/src/dotty/tools/dotc/FromTasty.scala @@ -64,6 +64,9 @@ object FromTasty extends Driver { } class ReadTastyTreesFromClasses extends FrontEnd { + + override def isTyper = false + override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = units.map(readTASTY) From 3e0be576398673d33ff15a6e117e04c5d5cc016f Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 7 Apr 2016 21:43:50 +0200 Subject: [PATCH 06/21] Add dotty.annotation.internal.SourceFile annotation --- src/dotty/tools/dotc/core/Annotations.scala | 3 +++ src/dotty/tools/dotc/core/Definitions.scala | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/dotty/tools/dotc/core/Annotations.scala b/src/dotty/tools/dotc/core/Annotations.scala index dc4897233d89..5f96a60e649b 100644 --- a/src/dotty/tools/dotc/core/Annotations.scala +++ b/src/dotty/tools/dotc/core/Annotations.scala @@ -94,6 +94,9 @@ object Annotations { def makeChild(sym: Symbol)(implicit ctx: Context) = deferred(defn.ChildAnnot, implicit ctx => New(defn.ChildAnnotType.appliedTo(sym.owner.thisType.select(sym.name, sym)), Nil)) + + def makeSourceFile(path: String)(implicit ctx: Context) = + apply(defn.SourceFileAnnot, Literal(Constant(path))) } def ThrowsAnnotation(cls: ClassSymbol)(implicit ctx: Context) = { diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala index d8c882d5c704..6625cff3f7fd 100644 --- a/src/dotty/tools/dotc/core/Definitions.scala +++ b/src/dotty/tools/dotc/core/Definitions.scala @@ -456,6 +456,8 @@ class Definitions { def RemoteAnnot(implicit ctx: Context) = RemoteAnnotType.symbol.asClass lazy val RepeatedAnnotType = ctx.requiredClassRef("dotty.annotation.internal.Repeated") def RepeatedAnnot(implicit ctx: Context) = RepeatedAnnotType.symbol.asClass + lazy val SourceFileAnnotType = ctx.requiredClassRef("dotty.annotation.internal.SourceFile") + def SourceFileAnnot(implicit ctx: Context) = SourceFileAnnotType.symbol.asClass lazy val ScalaSignatureAnnotType = ctx.requiredClassRef("scala.reflect.ScalaSignature") def ScalaSignatureAnnot(implicit ctx: Context) = ScalaSignatureAnnotType.symbol.asClass lazy val ScalaLongSignatureAnnotType = ctx.requiredClassRef("scala.reflect.ScalaLongSignature") From b3b3f3c31946c69b8ea03af352331482268fc16a Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 7 Apr 2016 21:46:10 +0200 Subject: [PATCH 07/21] Fix reading of SourceFile attribute from Tasty The previous path name always had a "Simple(...)" wrapped around it. --- src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala b/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala index d62762571f71..6d0e73efba9b 100644 --- a/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala +++ b/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala @@ -18,8 +18,10 @@ object DottyUnpickler { class BadSignature(msg: String) extends RuntimeException(msg) class SourceFileUnpickler extends SectionUnpickler[SourceFile]("Sourcefile") { - def unpickle(reader: TastyReader, tastyName: TastyName.Table) = - new SourceFile(tastyName(reader.readNameRef()).toString, Seq()) + def unpickle(reader: TastyReader, tastyName: TastyName.Table) = { + val TastyName.Simple(sourceName) = tastyName(reader.readNameRef()) + new SourceFile(sourceName.toString, Seq()) + } } class TreeSectionUnpickler extends SectionUnpickler[TreeUnpickler]("ASTs") { From cb1f38669abb118697e1351822fa6705f52dcce7 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 7 Apr 2016 21:46:39 +0200 Subject: [PATCH 08/21] Pickle sourcefile attribute with canonical path --- src/dotty/tools/dotc/transform/Pickler.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dotty/tools/dotc/transform/Pickler.scala b/src/dotty/tools/dotc/transform/Pickler.scala index c5b223d53aa9..7b77ef961919 100644 --- a/src/dotty/tools/dotc/transform/Pickler.scala +++ b/src/dotty/tools/dotc/transform/Pickler.scala @@ -68,7 +68,7 @@ class Pickler extends Phase { private def pickleSourcefile(pickler: TastyPickler, source: SourceFile): Unit = { val buf = new TastyBuffer(10) pickler.newSection("Sourcefile", buf) - buf.writeNat(pickler.nameBuffer.nameIndex(source.file.path).index) + buf.writeNat(pickler.nameBuffer.nameIndex(source.file.canonicalPath).index) } override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = { From 8ddfa83177c5962e06a0a2ee2365e2e62ea6dfa0 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 7 Apr 2016 21:47:22 +0200 Subject: [PATCH 09/21] Add unpickled source file path as annotation to root symbols --- src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala b/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala index 6d0e73efba9b..edaeacd9a8bd 100644 --- a/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala +++ b/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala @@ -3,13 +3,14 @@ package dotc package core package tasty -import Contexts._, SymDenotations._ +import Contexts._, SymDenotations._, Symbols._ import dotty.tools.dotc.ast.tpd import TastyUnpickler._, TastyBuffer._ import dotty.tools.dotc.core.tasty.DottyUnpickler.{SourceFileUnpickler, TreeSectionUnpickler, PositionsSectionUnpickler} import util.Positions._ import util.{SourceFile, NoSource} import PositionUnpickler._ +import Annotations.Annotation import classfile.ClassfileParser object DottyUnpickler { @@ -43,21 +44,24 @@ class DottyUnpickler(bytes: Array[Byte]) extends ClassfileParser.Embedded { val unpickler = new TastyUnpickler(bytes) private val treeUnpickler = unpickler.unpickle(new TreeSectionUnpickler).get + private val source = unpickler.unpickle(new SourceFileUnpickler).getOrElse(NoSource) /** Enter all toplevel classes and objects into their scopes * @param roots a set of SymDenotations that should be overwritten by unpickling */ - def enter(roots: Set[SymDenotation])(implicit ctx: Context): Unit = + def enter(roots: Set[SymDenotation])(implicit ctx: Context): Unit = { treeUnpickler.enterTopLevel(roots) + if (source.exists) + for (root <- roots) root.addAnnotation(Annotation.makeSourceFile(source.path)) + } /** The unpickled trees, and the source file they come from * @param readPositions if true, trees get decorated with position information. */ def body(readPositions: Boolean = false)(implicit ctx: Context): (List[Tree], SourceFile) = { - val source = unpickler.unpickle(new SourceFileUnpickler).getOrElse(NoSource) if (readPositions) for ((totalRange, positions) <- unpickler.unpickle(new PositionsSectionUnpickler)) treeUnpickler.usePositions(totalRange, positions) - (treeUnpickler.unpickle(), source) + (treeUnpickler.unpickle(source), source) } } From cc7acead9472643a2bdf73ac49d8d28f444d5fce Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 7 Apr 2016 21:50:00 +0200 Subject: [PATCH 10/21] Take SourceFile annotations into account when computing sourceFile If a file was loaded from TASTY, it can not still have a non-null source file, since the source file is unpickled into the annotation of a top-level class. Also, fix typo in previous commit. --- src/dotty/tools/dotc/core/Symbols.scala | 28 +++++++++++-------- .../dotc/core/tasty/DottyUnpickler.scala | 2 +- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala index 2a76f18d8ff6..d40acdfa797b 100644 --- a/src/dotty/tools/dotc/core/Symbols.scala +++ b/src/dotty/tools/dotc/core/Symbols.scala @@ -21,6 +21,7 @@ import StdNames._ import NameOps._ import ast.tpd.Tree import ast.TreeTypeMap +import Constants.Constant import Denotations.{ Denotation, SingleDenotation, MultiDenotation } import collection.mutable import io.AbstractFile @@ -463,20 +464,23 @@ object Symbols { denot.topLevelClass.symbol.associatedFile /** The class file from which this class was generated, null if not applicable. */ - final def binaryFile(implicit ctx: Context): AbstractFile = - pickFile(associatedFile, classFile = true) + final def binaryFile(implicit ctx: Context): AbstractFile = { + val file = associatedFile + if (file != null && file.path.endsWith("class")) file else null + } /** The source file from which this class was generated, null if not applicable. */ - final def sourceFile(implicit ctx: Context): AbstractFile = - pickFile(associatedFile, classFile = false) - - /** Desire to re-use the field in ClassSymbol which stores the source - * file to also store the classfile, but without changing the behavior - * of sourceFile (which is expected at least in the IDE only to - * return actual source code.) So sourceFile has classfiles filtered out. - */ - private def pickFile(file: AbstractFile, classFile: Boolean): AbstractFile = - if ((file eq null) || classFile != (file.path endsWith ".class")) null else file + final def sourceFile(implicit ctx: Context): AbstractFile = { + val file = associatedFile + if (file != null && !file.path.endsWith("class")) file + else denot.topLevelClass.getAnnotation(defn.SourceFileAnnot) match { + case Some(sourceAnnot) => sourceAnnot.argumentConstant(0) match { + case Some(Constant(path: String)) => AbstractFile.getFile(path) + case none => null + } + case none => null + } + } /** The position of this symbol, or NoPosition is symbol was not loaded * from source. diff --git a/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala b/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala index edaeacd9a8bd..afbf8ae073c5 100644 --- a/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala +++ b/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala @@ -62,6 +62,6 @@ class DottyUnpickler(bytes: Array[Byte]) extends ClassfileParser.Embedded { if (readPositions) for ((totalRange, positions) <- unpickler.unpickle(new PositionsSectionUnpickler)) treeUnpickler.usePositions(totalRange, positions) - (treeUnpickler.unpickle(source), source) + (treeUnpickler.unpickle(), source) } } From 29e5792ad7ea1209f0141000449649e8cb943b65 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 7 Apr 2016 21:57:55 +0200 Subject: [PATCH 11/21] Test cases --- tests/pickling/i1202a.scala | 7 +++++++ tests/pickling/i1202b.scala | 9 +++++++++ 2 files changed, 16 insertions(+) create mode 100644 tests/pickling/i1202a.scala create mode 100644 tests/pickling/i1202b.scala diff --git a/tests/pickling/i1202a.scala b/tests/pickling/i1202a.scala new file mode 100644 index 000000000000..0bc19f4e3c5c --- /dev/null +++ b/tests/pickling/i1202a.scala @@ -0,0 +1,7 @@ +class Test[T] { + def testMethod: Unit = + new Foo(this) +} +class Foo[T]() { + def this(ct: Test[T]) = this() +} diff --git a/tests/pickling/i1202b.scala b/tests/pickling/i1202b.scala new file mode 100644 index 000000000000..09d06170feee --- /dev/null +++ b/tests/pickling/i1202b.scala @@ -0,0 +1,9 @@ +package i1202 + +class Test() { + import Test._ + val myStatus = Unknown +} +object Test { + private val Unknown: Int = 0 +} From 88eb98ffc91f2954eb0ed305d19d46845f35ab33 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 7 Apr 2016 22:52:34 +0200 Subject: [PATCH 12/21] Fix flags when unpickling setters of parameter accessors ParamAccessor is not a pickled flag. This is not a problem for normal parameter accessors which are pickled as PARAM fields. But setters of parameter accessors also need to have the flag set (and Deferred reset). --- src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala | 5 +++++ tests/pickling/i1202c.scala | 1 + 2 files changed, 6 insertions(+) create mode 100644 tests/pickling/i1202c.scala diff --git a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index b547862b4083..d7f33c75c58f 100644 --- a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -596,6 +596,11 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) { vparamss.nestedMap(_.symbol), name == nme.CONSTRUCTOR) val resType = ctx.effectiveResultType(sym, typeParams, tpt.tpe) sym.info = ctx.methodType(typeParams, valueParamss, resType) + if (sym.isSetter && sym.accessedFieldOrGetter.is(ParamAccessor)) { + // reconstitute ParamAccessor flag of setters for var parameters, which is not pickled + sym.setFlag(ParamAccessor) + sym.resetFlag(Deferred) + } DefDef(tparams, vparamss, tpt) case VALDEF => sym.info = readType() diff --git a/tests/pickling/i1202c.scala b/tests/pickling/i1202c.scala new file mode 100644 index 000000000000..dde1f3aa65a0 --- /dev/null +++ b/tests/pickling/i1202c.scala @@ -0,0 +1 @@ +class Fail7(var in: Int) From 56b948c332993014e13c4c3e192b3573f9c46462 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 7 Apr 2016 23:44:05 +0200 Subject: [PATCH 13/21] Update TastyFormat for SeqLiteral SeqLiteral have an elemTpt, which was missing in format. --- src/dotty/tools/dotc/core/tasty/TastyFormat.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/src/dotty/tools/dotc/core/tasty/TastyFormat.scala index f3dabb517963..a9f2e753fccc 100644 --- a/src/dotty/tools/dotc/core/tasty/TastyFormat.scala +++ b/src/dotty/tools/dotc/core/tasty/TastyFormat.scala @@ -84,7 +84,7 @@ Standard-Section: "ASTs" TopLevelStat* MATCH Length sel_Term CaseDef* TRY Length expr_Term CaseDef* finalizer_Term? RETURN Length meth_ASTRef expr_Term? - REPEATED Length elem_Term* + REPEATED Length elem_Type elem_Term* BIND Length boundName_NameRef patType_Type pat_Term ALTERNATIVE Length alt_Term* UNAPPLY Length fun_Term ImplicitArg* pat_Type pat_Term* From 20175a01baf6dc3129f72c16f205832901098956 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 7 Apr 2016 23:48:17 +0200 Subject: [PATCH 14/21] Fix unpickling of Java SeqLiterals Two problems were fixed: - isJava needs to look at function symbol, not its type (references to Java methods get normal MethodTypes not JavMethodTypes) - we also need to handle the case where the repeated argument is wrspped in a type ascription. --- .../tools/dotc/core/tasty/TreeUnpickler.scala | 14 +++++++++++--- tests/pickling/i1202d.scala | 4 ++++ 2 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 tests/pickling/i1202d.scala diff --git a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index d7f33c75c58f..ad6ddf7fe26f 100644 --- a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -807,9 +807,10 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) { tpd.Super(qual, mixName, ctx.mode.is(Mode.InSuperCall), mixClass) case APPLY => val fn = readTerm() - val isJava = fn.tpe.isInstanceOf[JavaMethodType] + val isJava = fn.symbol.is(JavaDefined) def readArg() = readTerm() match { - case SeqLiteral(elems, elemtpt) if isJava => JavaSeqLiteral(elems, elemtpt) + case SeqLiteral(elems, elemtpt) if isJava => + JavaSeqLiteral(elems, elemtpt) case arg => arg } tpd.Apply(fn, until(end)(readArg())) @@ -818,7 +819,14 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) { case PAIR => Pair(readTerm(), readTerm()) case TYPED => - Typed(readTerm(), readTpt()) + val expr = readTerm() + val tpt = readTpt() + val expr1 = expr match { + case SeqLiteral(elems, elemtpt) if tpt.tpe.isRef(defn.ArrayClass) => + JavaSeqLiteral(elems, elemtpt) + case expr => expr + } + Typed(expr1, tpt) case NAMEDARG => NamedArg(readName(), readTerm()) case ASSIGN => diff --git a/tests/pickling/i1202d.scala b/tests/pickling/i1202d.scala new file mode 100644 index 000000000000..d03adf1971fb --- /dev/null +++ b/tests/pickling/i1202d.scala @@ -0,0 +1,4 @@ +class Fail5 { + val someClass: Class[_] = ??? + val resultMethod = someClass.getMethod("result") +} From b37a2a898223049e6ac4c5ad2588e7018319709b Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 8 Apr 2016 09:12:05 +0200 Subject: [PATCH 15/21] Add source file for SourceFile annotation --- src/dotty/annotation/internal/SourceFile.scala | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/dotty/annotation/internal/SourceFile.scala diff --git a/src/dotty/annotation/internal/SourceFile.scala b/src/dotty/annotation/internal/SourceFile.scala new file mode 100644 index 000000000000..c49fc2c8dc4a --- /dev/null +++ b/src/dotty/annotation/internal/SourceFile.scala @@ -0,0 +1,10 @@ +package dotty.annotation.internal + +import scala.annotation.Annotation + +/** An annotation to record a Scala2 pickled alias. + * @param aliased A TermRef pointing to the aliased field. + */ +class SourceFile(path: String) extends Annotation { + +} From 5debb0971aff9cfa68ed9db4158753fbd8d6b519 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 8 Apr 2016 15:04:00 +0200 Subject: [PATCH 16/21] Explain isTyper field in Phase. --- src/dotty/tools/dotc/core/Phases.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/dotty/tools/dotc/core/Phases.scala b/src/dotty/tools/dotc/core/Phases.scala index ce87506ae9f5..4b2861452d0c 100644 --- a/src/dotty/tools/dotc/core/Phases.scala +++ b/src/dotty/tools/dotc/core/Phases.scala @@ -291,7 +291,11 @@ object Phases { */ def relaxedTyping: Boolean = false - /** Overridden by FrontEnd */ + /** Is this phase the standard typerphase? True for FrontEnd, but + * not for other first phases (such as FromTasty). The predicate + * is tested in some places that perform checks and corrections. It's + * different from isAfterTyper (and cheaper to test). + */ def isTyper = false def exists: Boolean = true From f9d27c9f63ed1852b372757aadc517ec02cb17ff Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 8 Apr 2016 15:05:09 +0200 Subject: [PATCH 17/21] Store source files as normal paths, not canonical ones. This is the same as what Java does for its ClassFile attribute. --- .../tools/dotc/transform/ExpandPrivate.scala | 16 +++++++++++++++- src/dotty/tools/dotc/transform/Pickler.scala | 2 +- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/dotty/tools/dotc/transform/ExpandPrivate.scala b/src/dotty/tools/dotc/transform/ExpandPrivate.scala index a6f2034783cf..2e0759b8981f 100644 --- a/src/dotty/tools/dotc/transform/ExpandPrivate.scala +++ b/src/dotty/tools/dotc/transform/ExpandPrivate.scala @@ -16,6 +16,7 @@ import TreeTransforms._ import Decorators._ import ast.Trees._ import TreeTransforms._ +import java.io.File.separatorChar /** Make private term members that are accessed from another class * non-private by resetting the Private flag and expanding their name. @@ -58,7 +59,20 @@ class ExpandPrivate extends MiniPhaseTransform with IdentityDenotTransformer { t */ private def ensurePrivateAccessible(d: SymDenotation)(implicit ctx: Context) = if (d.is(PrivateTerm) && d.owner != ctx.owner.enclosingClass) { - assert(d.symbol.sourceFile == ctx.source.file, + // Paths `p1` and `p2` are similar if they have a common suffix that follows + // possibly different directory paths. That is, their common suffix extends + // in both cases either to the start of the path or to a file separator character. + def isSimilar(p1: String, p2: String): Boolean = { + var i = p1.length - 1 + var j = p2.length - 1 + while (i >= 0 && j >= 0 && p1(i) == p2(j) && p1(i) != separatorChar) { + i -= 1 + j -= 1 + } + (i < 0 || p1(i) == separatorChar) && + (j < 0 || p1(j) == separatorChar) + } + assert(isSimilar(d.symbol.sourceFile.path, ctx.source.file.path), i"private ${d.symbol.showLocated} in ${d.symbol.sourceFile} accessed from ${ctx.owner.showLocated} in ${ctx.source.file}") d.ensureNotPrivate.installAfter(thisTransform) } diff --git a/src/dotty/tools/dotc/transform/Pickler.scala b/src/dotty/tools/dotc/transform/Pickler.scala index 7b77ef961919..c5b223d53aa9 100644 --- a/src/dotty/tools/dotc/transform/Pickler.scala +++ b/src/dotty/tools/dotc/transform/Pickler.scala @@ -68,7 +68,7 @@ class Pickler extends Phase { private def pickleSourcefile(pickler: TastyPickler, source: SourceFile): Unit = { val buf = new TastyBuffer(10) pickler.newSection("Sourcefile", buf) - buf.writeNat(pickler.nameBuffer.nameIndex(source.file.canonicalPath).index) + buf.writeNat(pickler.nameBuffer.nameIndex(source.file.path).index) } override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = { From 5aa59ac17e6f48719f8b52048e0b86570e9399e3 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 9 Apr 2016 11:16:10 +0200 Subject: [PATCH 18/21] Simplify handling of sourcefiles in Tasty info Instead of separate source file sections, pickle SourceFile as an annotation of all toplevel classes. We represent it like this anyway when reading back Tasty-defined classes. --- src/dotty/tools/dotc/FromTasty.scala | 4 ++-- .../dotc/core/tasty/DottyUnpickler.scala | 19 ++++--------------- .../tools/dotc/core/tasty/TastyFormat.scala | 2 -- src/dotty/tools/dotc/transform/Pickler.scala | 17 ++++------------- .../tools/dotc/transform/PostTyper.scala | 8 +++++++- 5 files changed, 17 insertions(+), 33 deletions(-) diff --git a/src/dotty/tools/dotc/FromTasty.scala b/src/dotty/tools/dotc/FromTasty.scala index 14fd8ad6cf59..05e97f30a5de 100644 --- a/src/dotty/tools/dotc/FromTasty.scala +++ b/src/dotty/tools/dotc/FromTasty.scala @@ -86,8 +86,8 @@ object FromTasty extends Driver { case info: ClassfileLoader => info.load(clsd) match { case Some(unpickler: DottyUnpickler) => - val (List(unpickled), source) = unpickler.body(readPositions = true) - val unit1 = new CompilationUnit(source) + val List(unpickled) = unpickler.body(readPositions = true) + val unit1 = new CompilationUnit(new SourceFile(clsd.symbol.sourceFile, Seq())) unit1.tpdTree = unpickled unit1.unpicklers += (clsd.classSymbol -> unpickler.unpickler) force.traverse(unit1.tpdTree) diff --git a/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala b/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala index afbf8ae073c5..0ad5d69668c8 100644 --- a/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala +++ b/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala @@ -6,7 +6,6 @@ package tasty import Contexts._, SymDenotations._, Symbols._ import dotty.tools.dotc.ast.tpd import TastyUnpickler._, TastyBuffer._ -import dotty.tools.dotc.core.tasty.DottyUnpickler.{SourceFileUnpickler, TreeSectionUnpickler, PositionsSectionUnpickler} import util.Positions._ import util.{SourceFile, NoSource} import PositionUnpickler._ @@ -18,13 +17,6 @@ object DottyUnpickler { /** Exception thrown if classfile is corrupted */ class BadSignature(msg: String) extends RuntimeException(msg) - class SourceFileUnpickler extends SectionUnpickler[SourceFile]("Sourcefile") { - def unpickle(reader: TastyReader, tastyName: TastyName.Table) = { - val TastyName.Simple(sourceName) = tastyName(reader.readNameRef()) - new SourceFile(sourceName.toString, Seq()) - } - } - class TreeSectionUnpickler extends SectionUnpickler[TreeUnpickler]("ASTs") { def unpickle(reader: TastyReader, tastyName: TastyName.Table) = new TreeUnpickler(reader, tastyName) @@ -41,27 +33,24 @@ object DottyUnpickler { */ class DottyUnpickler(bytes: Array[Byte]) extends ClassfileParser.Embedded { import tpd._ + import DottyUnpickler._ val unpickler = new TastyUnpickler(bytes) private val treeUnpickler = unpickler.unpickle(new TreeSectionUnpickler).get - private val source = unpickler.unpickle(new SourceFileUnpickler).getOrElse(NoSource) /** Enter all toplevel classes and objects into their scopes * @param roots a set of SymDenotations that should be overwritten by unpickling */ - def enter(roots: Set[SymDenotation])(implicit ctx: Context): Unit = { + def enter(roots: Set[SymDenotation])(implicit ctx: Context): Unit = treeUnpickler.enterTopLevel(roots) - if (source.exists) - for (root <- roots) root.addAnnotation(Annotation.makeSourceFile(source.path)) - } /** The unpickled trees, and the source file they come from * @param readPositions if true, trees get decorated with position information. */ - def body(readPositions: Boolean = false)(implicit ctx: Context): (List[Tree], SourceFile) = { + def body(readPositions: Boolean = false)(implicit ctx: Context): List[Tree] = { if (readPositions) for ((totalRange, positions) <- unpickler.unpickle(new PositionsSectionUnpickler)) treeUnpickler.usePositions(totalRange, positions) - (treeUnpickler.unpickle(), source) + treeUnpickler.unpickle() } } diff --git a/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/src/dotty/tools/dotc/core/tasty/TastyFormat.scala index a9f2e753fccc..ea7e985c9a1a 100644 --- a/src/dotty/tools/dotc/core/tasty/TastyFormat.scala +++ b/src/dotty/tools/dotc/core/tasty/TastyFormat.scala @@ -184,8 +184,6 @@ Note: Tree tags are grouped into 5 categories that determine what follows, and t Category 4 (tags 112-127): tag Nat AST Category 5 (tags 128-255): tag Length -Standard Section: "Sourcefile" sourcefile_NameRef - Standard Section: "Positions" sourceLength_Nat Assoc* Assoc = addr_Delta offset_Delta offset_Delta? diff --git a/src/dotty/tools/dotc/transform/Pickler.scala b/src/dotty/tools/dotc/transform/Pickler.scala index c5b223d53aa9..e8d6d03bfd9c 100644 --- a/src/dotty/tools/dotc/transform/Pickler.scala +++ b/src/dotty/tools/dotc/transform/Pickler.scala @@ -11,7 +11,6 @@ import Periods._ import Phases._ import Symbols._ import Flags.Module -import util.SourceFile import collection.mutable /** This phase pickles trees */ @@ -48,8 +47,6 @@ class Pickler extends Phase { treePkl.pickle(tree :: Nil) pickler.addrOfTree = treePkl.buf.addrOfTree pickler.addrOfSym = treePkl.addrOfSym - if (unit.source.exists) - pickleSourcefile(pickler, unit.source) if (tree.pos.exists) new PositionPickler(pickler, treePkl.buf.addrOfTree).picklePositions(tree :: Nil, tree.pos) @@ -65,12 +62,6 @@ class Pickler extends Phase { } } - private def pickleSourcefile(pickler: TastyPickler, source: SourceFile): Unit = { - val buf = new TastyBuffer(10) - pickler.newSection("Sourcefile", buf) - buf.writeNat(pickler.nameBuffer.nameIndex(source.file.path).index) - } - override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = { val result = super.runOn(units) if (ctx.settings.YtestPickler.value) @@ -89,16 +80,16 @@ class Pickler extends Phase { } pickling.println("************* entered toplevel ***********") for ((cls, unpickler) <- unpicklers) { - val (unpickled, source) = unpickler.body(readPositions = true) - testSame(i"$unpickled%\n%", beforePickling(cls), cls, source) + val unpickled = unpickler.body(readPositions = true) + testSame(i"$unpickled%\n%", beforePickling(cls), cls) } } - private def testSame(unpickled: String, previous: String, cls: ClassSymbol, source: SourceFile)(implicit ctx: Context) = + private def testSame(unpickled: String, previous: String, cls: ClassSymbol)(implicit ctx: Context) = if (previous != unpickled) { output("before-pickling.txt", previous) output("after-pickling.txt", unpickled) - ctx.error(s"""pickling difference for ${cls.fullName} in $source, for details: + ctx.error(s"""pickling difference for ${cls.fullName} in ${cls.sourceFile}, for details: | | diff before-pickling.txt after-pickling.txt""".stripMargin) } diff --git a/src/dotty/tools/dotc/transform/PostTyper.scala b/src/dotty/tools/dotc/transform/PostTyper.scala index 01f9f6317e6e..0a4964e35dd1 100644 --- a/src/dotty/tools/dotc/transform/PostTyper.scala +++ b/src/dotty/tools/dotc/transform/PostTyper.scala @@ -36,6 +36,8 @@ import Symbols._, TypeUtils._ * * (8) Replaces self references by name with `this` * + * (9) Adds SourceFile annotations to all top-level classes and objects + * * The reason for making this a macro transform is that some functions (in particular * super and protected accessors and instantiation checks) are naturally top-down and * don't lend themselves to the bottom-up approach of a mini phase. The other two functions @@ -224,7 +226,11 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran transformMemberDef(tree) val sym = tree.symbol val tree1 = - if (sym.isClass) tree + if (sym.isClass) { + if (sym.owner.is(Package) && ctx.compilationUnit.source.exists) + sym.addAnnotation(Annotation.makeSourceFile(ctx.compilationUnit.source.file.path)) + tree + } else { Checking.typeChecker.traverse(tree.rhs) cpy.TypeDef(tree)(rhs = TypeTree(tree.symbol.info)) From 0907f5bd5cc9f57b01c5b73403463c20b857d632 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 9 Apr 2016 12:27:14 +0200 Subject: [PATCH 19/21] Avoid creating a SourceFile annotation for SourceFile itself This leads to an infinite cycle when trying to unpickling, because the modifiers and annotations of a symbol are read before the symbol itself is created. See #1212 for the general case. --- src/dotty/tools/dotc/transform/PostTyper.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dotty/tools/dotc/transform/PostTyper.scala b/src/dotty/tools/dotc/transform/PostTyper.scala index 0a4964e35dd1..fcde59b24a03 100644 --- a/src/dotty/tools/dotc/transform/PostTyper.scala +++ b/src/dotty/tools/dotc/transform/PostTyper.scala @@ -227,7 +227,9 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran val sym = tree.symbol val tree1 = if (sym.isClass) { - if (sym.owner.is(Package) && ctx.compilationUnit.source.exists) + if (sym.owner.is(Package) && + ctx.compilationUnit.source.exists && + sym != defn.SourceFileAnnot) sym.addAnnotation(Annotation.makeSourceFile(ctx.compilationUnit.source.file.path)) tree } From 6942127668d0c9fe60e4b11d952adf2f7e1fee72 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 9 Apr 2016 12:28:06 +0200 Subject: [PATCH 20/21] Rearrange pickle tests 1) Move passing test to pickling 2) Add test case for #1212 in pending 3) Disable annotations/internal in pickling tests. They lead to a stable symbol error which is explainable (modifiers are read before symbol is created). --- test/dotc/tests.scala | 5 ++++- tests/pending/pickling/cyclic-annotations.scala | 1 + tests/{pending => }/pickling/i94-nada.scala | 0 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 tests/pending/pickling/cyclic-annotations.scala rename tests/{pending => }/pickling/i94-nada.scala (100%) diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala index 51b8b3dc5d93..a7d2873a52f2 100644 --- a/test/dotc/tests.scala +++ b/test/dotc/tests.scala @@ -200,7 +200,10 @@ class tests extends CompilerTest { @Test def tasty_new_all = compileFiles(newDir, testPickling) @Test def tasty_dotty = compileDir(sourceDir, "dotty", testPickling) - @Test def tasty_annotation_internal = compileDir(s"${dottyDir}annotation/", "internal", testPickling) + + // Disabled because we get stale symbol errors on the SourceFile annotation, which is normal. + // @Test def tasty_annotation_internal = compileDir(s"${dottyDir}annotation/", "internal", testPickling) + @Test def tasty_runtime = compileDir(s"$dottyDir", "runtime", testPickling) //TODO: issues with ./src/dotty/runtime/vc/VCPrototype.scala diff --git a/tests/pending/pickling/cyclic-annotations.scala b/tests/pending/pickling/cyclic-annotations.scala new file mode 100644 index 000000000000..b975afe37015 --- /dev/null +++ b/tests/pending/pickling/cyclic-annotations.scala @@ -0,0 +1 @@ +@ann class ann extends scala.annotation.Annotation diff --git a/tests/pending/pickling/i94-nada.scala b/tests/pickling/i94-nada.scala similarity index 100% rename from tests/pending/pickling/i94-nada.scala rename to tests/pickling/i94-nada.scala From 7ea24c63ad57029b8e68ff00f5978e0e9058f60b Mon Sep 17 00:00:00 2001 From: VladimirNik Date: Wed, 13 Apr 2016 19:11:03 +0200 Subject: [PATCH 21/21] Update TASTY tests for dotty/src --- test/dotc/tests.scala | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala index a7d2873a52f2..b646c72d5573 100644 --- a/test/dotc/tests.scala +++ b/test/dotc/tests.scala @@ -205,9 +205,7 @@ class tests extends CompilerTest { // @Test def tasty_annotation_internal = compileDir(s"${dottyDir}annotation/", "internal", testPickling) @Test def tasty_runtime = compileDir(s"$dottyDir", "runtime", testPickling) - - //TODO: issues with ./src/dotty/runtime/vc/VCPrototype.scala - //@Test def tasty_runtime_vc = compileDir(s"${dottyDir}runtime/", "vc", testPickling) + @Test def tasty_runtime_vc = compileDir(s"${dottyDir}runtime/", "vc", testPickling) @Test def tasty_tools = compileDir(dottyDir, "tools", testPickling) @@ -217,11 +215,7 @@ class tests extends CompilerTest { "scalaPrimitives.scala" ) map (s"${backendDir}jvm/" + _), testPickling) - //TODO: issue with ./src/dotty/tools/backend/sjs/JSCodeGen.scala - @Test def tasty_backend_sjs = compileList("tasty_backend_sjs", List( - "GenSJSIR.scala", "JSDefinitions.scala", "JSEncoding.scala", "JSInterop.scala", - "JSPositions.scala", "JSPrimitives.scala", "ScopedVar.scala" - ) map (s"${backendDir}sjs/" + _), testPickling) + @Test def tasty_backend_sjs = compileDir(s"${backendDir}", "sjs", testPickling) @Test def tasty_dotc = compileDir(toolsDir, "dotc", testPickling) @Test def tasty_dotc_ast = compileDir(dotcDir, "ast", testPickling) @@ -252,12 +246,7 @@ class tests extends CompilerTest { @Test def tasty_dotc_printing = compileDir(dotcDir, "printing", testPickling) - //TODO: issues with ./src/dotty/tools/dotc/repl/CompilingInterpreter.scala, - //./src/dotty/tools/dotc/repl/InterpreterLoop.scala - @Test def tasty_dotc_repl = compileList("tasty_dotc_repl", List( - "AbstractFileClassLoader.scala", "ConsoleWriter.scala", "InteractiveReader.scala", - "Interpreter.scala", "Main.scala", "NewLinePrintWriter.scala", "REPL.scala", "SimpleReader.scala" - ) map (dottyReplDir + _), testPickling) + @Test def tasty_dotc_repl = compileDir(dotcDir, "repl", testPickling) //@Test def tasty_dotc_reporting = compileDir(dotcDir, "reporting", testPickling) @Test def tasty_dotc_rewrite = compileDir(dotcDir, "rewrite", testPickling)