diff options
248 files changed, 912 insertions, 2339 deletions
diff --git a/README.rst b/README.rst index 7a1ed1dcf4..c871adb908 100644 --- a/README.rst +++ b/README.rst @@ -7,11 +7,11 @@ and how to build it. For information about Scala as a language, you can visit the web site http://www.scala-lang.org/ Part I. The repository layout --------------------------------------------------------------------------------- +-------------------------------------------------------------------------------- Follows the file layout of the Scala repository. Files marked with a †are not part of the repository but are either automatically generated by the -build script or user-created if needed. This is not a complete listing. :: +build script or user-created if needed. This is not a complete listing. :: scala/ +--build/ Build products output directory for ant. +--build.xml The main Ant build script. @@ -67,7 +67,7 @@ description of the four layers that SABBUS uses, from bottom to top: - ``strap``: a test layer used to check stability of the build. ^^^^^^^^^^^^^^^^^^^^^^^^ - DEPENDANT CHANGES: + DEPENDENT CHANGES: ^^^^^^^^^^^^^^^^^^^^^^^^ SABBUS compiles, for each layer, the Scala library first and the compiler next. That means that any changes in the library can immediately be used in the @@ -110,12 +110,12 @@ Part III. Common use-cases - ``ln -s build/quick/bin qbin`` (once): - ``ant && qbin/scalac -d sandbox sandbox/test.scala && qbin/scala -cp sandbox Test`` - + Incrementally builds quick, and then uses it to compile and run the file ``sandbox/test.scala``. This is a typical debug cycle. - ``ant replacelocker`` - + "unfreezes" locker by updating it to match the current source code. - This will delete quick so as not to mix classes compiled with different @@ -136,7 +136,7 @@ Part III. Common use-cases ANT_OPTS="-Xms512M -Xmx2048M -Xss1M -XX:MaxPermSize=128M" ant docs - ``ant dist`` - + Builds a distribution. - Rebuilds locker from scratch (to make sure it bootstraps). @@ -2440,7 +2440,6 @@ BOOTRAPING TEST AND TEST SUITE <runtests dir="${partest.dir}/${partest.srcdir}/run" includes="*.scala"/> <jvmtests dir="${partest.dir}/${partest.srcdir}/jvm" includes="*.scala"/> <residenttests dir="${partest.dir}/${partest.srcdir}/res" includes="*.res"/> - <buildmanagertests dir="${partest.dir}/${partest.srcdir}/buildmanager" includes="*"/> <scalaptests dir="${partest.dir}/${partest.srcdir}/scalap" includes="**/*.scala"/> <scalachecktests dir="${partest.dir}/${partest.srcdir}/scalacheck"> <include name="*.scala"/> diff --git a/project/Partest.scala b/project/Partest.scala index fbb0a2a980..2ea41ba80b 100644 --- a/project/Partest.scala +++ b/project/Partest.scala @@ -33,11 +33,10 @@ object partest { // What's fun here is that we want "*.scala" files *and* directories in the base directory... def partestResources(base: File, testType: String): PathFinder = testType match { case "res" => base ** "*.res" - case "buildmanager" => base * "*" // TODO - Only allow directories that have "*.scala" children... case _ => base * "*" filter { f => !f.getName.endsWith(".obj") && (f.isDirectory || f.getName.endsWith(".scala")) } } - lazy val partestTestTypes = Seq("run", "jvm", "pos", "neg", "buildmanager", "res", "shootout", "scalap", "specialized", "presentation", "scalacheck") + lazy val partestTestTypes = Seq("run", "jvm", "pos", "neg", "res", "shootout", "scalap", "specialized", "presentation", "scalacheck") // TODO - Figure out how to specify only a subset of resources... def partestTestsTask(testDirs: ScopedSetting[Map[String,File]]): Project.Initialize[Task[Map[String, Seq[File]]]] = diff --git a/project/project/Build.scala b/project/project/Build.scala index 902e8b0fb3..d3a08b62ba 100644 --- a/project/project/Build.scala +++ b/project/project/Build.scala @@ -3,5 +3,5 @@ object PluginDef extends Build { override def projects = Seq(root) lazy val root = Project("plugins", file(".")) dependsOn(proguard, git) lazy val proguard = uri("git://github.com/jsuereth/xsbt-proguard-plugin.git#sbt-0.12") - lazy val git = uri("git://github.com/sbt/sbt-git-plugin.git#scala-build") + lazy val git = uri("git://github.com/sbt/sbt-git.git#scala-build") } diff --git a/src/compiler/scala/reflect/macros/runtime/Enclosures.scala b/src/compiler/scala/reflect/macros/runtime/Enclosures.scala index e8b2961611..8fe0b09700 100644 --- a/src/compiler/scala/reflect/macros/runtime/Enclosures.scala +++ b/src/compiler/scala/reflect/macros/runtime/Enclosures.scala @@ -8,6 +8,10 @@ trait Enclosures { import universe._ + type MacroRole = analyzer.MacroRole + def APPLY_ROLE = analyzer.APPLY_ROLE + def macroRole: MacroRole + private lazy val site = callsiteTyper.context private lazy val enclTrees = site.enclosingContextChain map (_.tree) private lazy val enclPoses = enclosingMacros map (_.macroApplication.pos) filterNot (_ eq NoPosition) diff --git a/src/compiler/scala/reflect/macros/runtime/Typers.scala b/src/compiler/scala/reflect/macros/runtime/Typers.scala index f9add91b9a..7e268247dd 100644 --- a/src/compiler/scala/reflect/macros/runtime/Typers.scala +++ b/src/compiler/scala/reflect/macros/runtime/Typers.scala @@ -1,6 +1,8 @@ package scala.reflect.macros package runtime +import scala.reflect.internal.Mode + trait Typers { self: Context => @@ -22,7 +24,7 @@ trait Typers { // typechecking uses silent anyways (e.g. in typedSelect), so you'll only waste your time // I'd advise fixing the root cause: finding why the context is not set to report errors // (also see reflect.runtime.ToolBoxes.typeCheckExpr for a workaround that might work for you) - wrapper(callsiteTyper.silent(_.typed(tree, universe.analyzer.EXPRmode, pt)) match { + wrapper(callsiteTyper.silent(_.typed(tree, Mode.EXPRmode, pt)) match { case universe.analyzer.SilentResultValue(result) => macroLogVerbose(result) result @@ -62,4 +64,4 @@ trait Typers { def resetAllAttrs(tree: Tree): Tree = universe.resetAllAttrs(tree) def resetLocalAttrs(tree: Tree): Tree = universe.resetLocalAttrs(tree) -}
\ No newline at end of file +} diff --git a/src/compiler/scala/reflect/reify/phases/Reshape.scala b/src/compiler/scala/reflect/reify/phases/Reshape.scala index 75384ddce1..5dd5f08b45 100644 --- a/src/compiler/scala/reflect/reify/phases/Reshape.scala +++ b/src/compiler/scala/reflect/reify/phases/Reshape.scala @@ -89,8 +89,8 @@ trait Reshape { } private def undoMacroExpansion(tree: Tree): Tree = - tree.attachments.get[MacroExpansionAttachment] match { - case Some(MacroExpansionAttachment(original)) => + tree.attachments.get[analyzer.MacroExpansionAttachment] match { + case Some(analyzer.MacroExpansionAttachment(original, _)) => original match { // this hack is necessary until I fix implicit macros // so far tag materialization is implemented by sneaky macros hidden in scala-compiler.jar diff --git a/src/compiler/scala/tools/ant/ScalaTool.scala b/src/compiler/scala/tools/ant/ScalaTool.scala index 57d24f6213..633145a97c 100644 --- a/src/compiler/scala/tools/ant/ScalaTool.scala +++ b/src/compiler/scala/tools/ant/ScalaTool.scala @@ -108,7 +108,7 @@ class ScalaTool extends ScalaMatchingTask { * for general purpose scripts, as this does not assume all elements are * relative to the Ant `basedir`. Additionally, the platform specific * demarcation of any script variables (e.g. `${SCALA_HOME}` or - * `%SCALA_HOME%`) can be specified in a platform independant way (e.g. + * `%SCALA_HOME%`) can be specified in a platform independent way (e.g. * `@SCALA_HOME@`) and automatically translated for you. */ def setClassPath(input: String) { diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 8746a7fd8d..05d0bcf6b0 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -16,7 +16,6 @@ import scala.reflect.internal.util.{ OffsetPosition, SourceFile, NoSourceFile, B import scala.reflect.internal.pickling.{ PickleBuffer, PickleFormat } import symtab.{ Flags, SymbolTable, SymbolLoaders, SymbolTrackers } import symtab.classfile.Pickler -import dependencies.DependencyAnalysis import plugins.Plugins import ast._ import ast.parser._ @@ -329,9 +328,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) } } - if (!dependencyAnalysis.off) - dependencyAnalysis.loadDependencyAnalysis() - if (settings.verbose.value || settings.Ylogcp.value) { // Uses the "do not truncate" inform informComplete("[search path for source files: " + classPath.sourcepaths.mkString(",") + "]") @@ -606,14 +602,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) val runsRightAfter = None } with GenASM - // This phase is optional: only added if settings.make option is given. - // phaseName = "dependencyAnalysis" - object dependencyAnalysis extends { - val global: Global.this.type = Global.this - val runsAfter = List("jvm") - val runsRightAfter = None - } with DependencyAnalysis - // phaseName = "terminal" object terminal extends { val global: Global.this.type = Global.this @@ -1472,8 +1460,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) } /** Compile list of source files */ - def compileSources(_sources: List[SourceFile]) { - val sources = dependencyAnalysis calculateFiles _sources.distinct + def compileSources(sources: List[SourceFile]) { // there is a problem already, e.g. a plugin was passed a bad option if (reporter.hasErrors) return @@ -1568,10 +1555,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) symSource.keys foreach (x => resetPackageClass(x.owner)) informTime("total", startTime) - // record dependency data - if (!dependencyAnalysis.off) - dependencyAnalysis.saveDependencyAnalysis() - // Clear any sets or maps created via perRunCaches. perRunCaches.clearAll() diff --git a/src/compiler/scala/tools/nsc/Main.scala b/src/compiler/scala/tools/nsc/Main.scala index a4b22b0e11..c3c919fae4 100644 --- a/src/compiler/scala/tools/nsc/Main.scala +++ b/src/compiler/scala/tools/nsc/Main.scala @@ -7,7 +7,6 @@ package scala.tools.nsc import java.io.File import File.pathSeparator -import scala.tools.nsc.interactive.{ RefinedBuildManager, SimpleBuildManager } import scala.tools.nsc.io.AbstractFile /** The main class for NSC, a compiler for the programming @@ -42,23 +41,6 @@ object Main extends Driver with EvalLoop { askShutdown false } - else if (settings.Ybuilderdebug.value != "none") { - def fileSet(files : List[String]) = Set.empty ++ (files map AbstractFile.getFile) - - val buildManager = settings.Ybuilderdebug.value match { - case "simple" => new SimpleBuildManager(settings) - case _ => new RefinedBuildManager(settings) - } - buildManager.addSourceFiles(fileSet(command.files)) - - // enter resident mode - loop { line => - val args = line.split(' ').toList - val command = new CompilerCommand(args.toList, settings) - buildManager.update(fileSet(command.files), Set.empty) - } - false - } else true override def newCompiler(): Global = diff --git a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala index deea4de707..602366a201 100644 --- a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala @@ -168,6 +168,13 @@ abstract class NodePrinters { } } + def typeApplyCommon(tree: Tree, fun: Tree, args: List[Tree]) { + printMultiline(tree) { + traverse(fun) + traverseList("[]", "type argument")(args) + } + } + def treePrefix(tree: Tree) = showPosition(tree) + tree.productPrefix def printMultiline(tree: Tree)(body: => Unit) { printMultiline(treePrefix(tree), showAttributes(tree))(body) @@ -203,9 +210,11 @@ abstract class NodePrinters { showPosition(tree) tree match { - case AppliedTypeTree(tpt, args) => applyCommon(tree, tpt, args) - case ApplyDynamic(fun, args) => applyCommon(tree, fun, args) - case Apply(fun, args) => applyCommon(tree, fun, args) + case ApplyDynamic(fun, args) => applyCommon(tree, fun, args) + case Apply(fun, args) => applyCommon(tree, fun, args) + + case TypeApply(fun, args) => typeApplyCommon(tree, fun, args) + case AppliedTypeTree(tpt, args) => typeApplyCommon(tree, tpt, args) case Throw(Ident(name)) => printSingle(tree, name) @@ -312,11 +321,6 @@ abstract class NodePrinters { } case This(qual) => printSingle(tree, qual) - case TypeApply(fun, args) => - printMultiline(tree) { - traverse(fun) - traverseList("[]", "type argument")(args) - } case tt @ TypeTree() => println(showTypeTree(tt)) diff --git a/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala b/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala index 5cc4404ca1..08602f87dc 100644 --- a/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala +++ b/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala @@ -38,14 +38,10 @@ trait JavaPlatform extends Platform { // replaces the tighter abstract definition here. If we had DOT typing rules, the two // types would be conjoined and everything would work out. Yet another reason to push for DOT. - private def depAnalysisPhase = - if (settings.make.isDefault) Nil - else List(dependencyAnalysis) - def platformPhases = List( flatten, // get rid of inner classes genASM // generate .class files - ) ++ depAnalysisPhase + ) lazy val externalEquals = getDecl(BoxesRunTimeClass, nme.equals_) lazy val externalEqualsNumNum = getDecl(BoxesRunTimeClass, nme.equalsNumNum) diff --git a/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala b/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala deleted file mode 100644 index 4d4b6589a0..0000000000 --- a/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala +++ /dev/null @@ -1,253 +0,0 @@ -package scala.tools.nsc -package dependencies - -import io.Path -import scala.collection._ -import scala.tools.nsc.io.AbstractFile -import scala.reflect.internal.util.SourceFile - -trait DependencyAnalysis extends SubComponent with Files { - import global._ - - val phaseName = "dependencyAnalysis" - - def off = settings.make.isDefault || settings.make.value == "all" - def shouldCheckClasspath = settings.make.value != "transitivenocp" - - def newPhase(prev: Phase) = new AnalysisPhase(prev) - - private def depPath = Path(settings.dependenciesFile.value) - def loadDependencyAnalysis(): Boolean = ( - depPath.path != "none" && depPath.isFile && loadFrom( - AbstractFile.getFile(depPath), - path => AbstractFile.getFile(depPath.parent resolve Path(path)) - ) - ) - def saveDependencyAnalysis(): Unit = { - if (!depPath.exists) - dependenciesFile = AbstractFile.getFile(depPath.createFile()) - - /** The directory where file lookup should start */ - val rootPath = depPath.parent.normalize - saveDependencies( - file => rootPath.relativize(Path(file.file).normalize).path - ) - } - - lazy val maxDepth = settings.make.value match { - case "changed" => 0 - case "immediate" => 1 - case _ => Int.MaxValue - } - - // todo: order insensible checking and, also checking timestamp? - def validateClasspath(cp1: String, cp2: String): Boolean = cp1 == cp2 - - def nameToFile(src: AbstractFile, name: String) = - settings.outputDirs.outputDirFor(src) - .lookupPathUnchecked(name.toString.replace(".", java.io.File.separator) + ".class", false) - - private var depFile: Option[AbstractFile] = None - - def dependenciesFile_=(file: AbstractFile) { - assert(file ne null) - depFile = Some(file) - } - - def dependenciesFile: Option[AbstractFile] = depFile - - def classpath = settings.classpath.value - def newDeps = new FileDependencies(classpath) - - var dependencies = newDeps - - def managedFiles = dependencies.dependencies.keySet - - /** Top level definitions per source file. */ - val definitions: mutable.Map[AbstractFile, List[Symbol]] = - new mutable.HashMap[AbstractFile, List[Symbol]] { - override def default(f: AbstractFile) = Nil - } - - /** External references used by source file. */ - val references: mutable.Map[AbstractFile, immutable.Set[String]] = - new mutable.HashMap[AbstractFile, immutable.Set[String]] { - override def default(f: AbstractFile) = immutable.Set() - } - - /** External references for inherited members used in the source file */ - val inherited: mutable.Map[AbstractFile, immutable.Set[Inherited]] = - new mutable.HashMap[AbstractFile, immutable.Set[Inherited]] { - override def default(f: AbstractFile) = immutable.Set() - } - - /** Write dependencies to the current file. */ - def saveDependencies(fromFile: AbstractFile => String) = - if(dependenciesFile.isDefined) - dependencies.writeTo(dependenciesFile.get, fromFile) - - /** Load dependencies from the given file and save the file reference for - * future saves. - */ - def loadFrom(f: AbstractFile, toFile: String => AbstractFile): Boolean = { - dependenciesFile = f - FileDependencies.readFrom(f, toFile) match { - case Some(fd) => - val success = if (shouldCheckClasspath) validateClasspath(fd.classpath, classpath) else true - dependencies = if (success) fd else { - if (settings.debug.value) - println("Classpath has changed. Nuking dependencies") - newDeps - } - - success - case None => false - } - } - - def calculateFiles(files: List[SourceFile]): List[SourceFile] = - if (off) files - else if (dependencies.isEmpty) { - println("No known dependencies. Compiling " + - (if (settings.debug.value) files.mkString(", ") else "everything")) - files - } else { - val (direct, indirect) = dependencies.invalidatedFiles(maxDepth); - val filtered = files.filter(x => { - val f = x.file.absolute - direct(f) || indirect(f) || !dependencies.containsFile(f); - }) - filtered match { - case Nil => println("No changes to recompile"); - case x => println("Recompiling " + ( - if(settings.debug.value) x.mkString(", ") else x.length + " files") - ) - } - filtered - } - - case class Inherited(qualifier: String, member: Name) - - class AnalysisPhase(prev: Phase) extends StdPhase(prev) { - - override def cancelled(unit: CompilationUnit) = - super.cancelled(unit) && !unit.isJava - - def apply(unit : global.CompilationUnit) { - val f = unit.source.file.file - // When we're passed strings by the interpreter - // they have no source file. We simply ignore this case - // as irrelevant to dependency analysis. - if (f != null){ - val source: AbstractFile = unit.source.file; - for (d <- unit.icode){ - val name = d.toString - d.symbol match { - case s : ModuleClassSymbol => - val isTopLevelModule = exitingPickler { !s.isImplClass && !s.isNestedClass } - - if (isTopLevelModule && (s.companionModule != NoSymbol)) { - dependencies.emits(source, nameToFile(unit.source.file, name)) - } - dependencies.emits(source, nameToFile(unit.source.file, name + "$")) - case _ => - dependencies.emits(source, nameToFile(unit.source.file, name)) - } - } - - dependencies.reset(source) - for (d <- unit.depends; if (d.sourceFile != null)){ - dependencies.depends(source, d.sourceFile) - } - } - - // find all external references in this compilation unit - val file = unit.source.file - references += file -> immutable.Set.empty[String] - inherited += file -> immutable.Set.empty[Inherited] - - val buf = new mutable.ListBuffer[Symbol] - - (new Traverser { - override def traverse(tree: Tree) { - if ((tree.symbol ne null) - && (tree.symbol != NoSymbol) - && (!tree.symbol.isPackage) - && (!tree.symbol.isJavaDefined) - && (!tree.symbol.tpe.isError) - && ((tree.symbol.sourceFile eq null) - || (tree.symbol.sourceFile.path != file.path)) - && (!tree.symbol.isClassConstructor)) { - updateReferences(tree.symbol.fullName) - // was "at uncurryPhase.prev", which is actually non-deterministic - // because the continuations plugin may or may not supply uncurry's - // immediately preceding phase. - enteringRefchecks(checkType(tree.symbol.tpe)) - } - - tree match { - case cdef: ClassDef if !cdef.symbol.hasPackageFlag && - !cdef.symbol.isAnonymousFunction => - if (cdef.symbol != NoSymbol) buf += cdef.symbol - // was "at erasurePhase.prev" - enteringExplicitOuter { - for (s <- cdef.symbol.info.decls) - s match { - case ts: TypeSymbol if !ts.isClass => - checkType(s.tpe) - case _ => - } - } - super.traverse(tree) - - case ddef: DefDef => - // was "at typer.prev" - enteringTyper { checkType(ddef.symbol.tpe) } - super.traverse(tree) - case a @ Select(q, n) if ((a.symbol != NoSymbol) && (q.symbol != null)) => // #2556 - if (!a.symbol.isConstructor && - !a.symbol.owner.isPackageClass && - !isSameType(q.tpe, a.symbol.owner.tpe)) - inherited += file -> - (inherited(file) + Inherited(q.symbol.tpe.resultType.safeToString, n)) - super.traverse(tree) - case _ => - super.traverse(tree) - } - } - - def checkType(tpe: Type): Unit = - tpe match { - case t: MethodType => - checkType(t.resultType) - for (s <- t.params) checkType(s.tpe) - - case t: TypeRef => - if (t.sym.isAliasType) { - updateReferences(t.typeSymbolDirect.fullName) - checkType(t.typeSymbolDirect.info) - } - updateReferences(t.typeSymbol.fullName) - for (tp <- t.args) checkType(tp) - - case t: PolyType => - checkType(t.resultType) - updateReferences(t.typeSymbol.fullName) - - case t: NullaryMethodType => - checkType(t.resultType) - updateReferences(t.typeSymbol.fullName) - - case t => - updateReferences(t.typeSymbol.fullName) - } - - def updateReferences(s: String): Unit = - references += file -> (references(file) + s) - - }).apply(unit.body) - - definitions(unit.source.file) = buf.toList - } - } -} diff --git a/src/compiler/scala/tools/nsc/dependencies/Files.scala b/src/compiler/scala/tools/nsc/dependencies/Files.scala deleted file mode 100644 index 194351a13f..0000000000 --- a/src/compiler/scala/tools/nsc/dependencies/Files.scala +++ /dev/null @@ -1,177 +0,0 @@ -package scala.tools.nsc -package dependencies - -import java.io.{InputStream, OutputStream, PrintStream, InputStreamReader, BufferedReader} -import io.{AbstractFile, PlainFile, VirtualFile} - -import scala.collection._ - - -trait Files { self : SubComponent => - - class FileDependencies(val classpath: String) { - import FileDependencies._ - - class Tracker extends mutable.OpenHashMap[AbstractFile, mutable.Set[AbstractFile]] { - override def default(key: AbstractFile) = { - this(key) = new mutable.HashSet[AbstractFile] - this(key) - } - } - - val dependencies = new Tracker - val targets = new Tracker - - def isEmpty = dependencies.isEmpty && targets.isEmpty - - def emits(source: AbstractFile, result: AbstractFile) = - targets(source) += result - def depends(from: AbstractFile, on: AbstractFile) = - dependencies(from) += on - - def reset(file: AbstractFile) = dependencies -= file - - def cleanEmpty = { - dependencies foreach {case (_, value) => - value retain (x => x.exists && (x ne removedFile))} - dependencies retain ((key, value) => key.exists && !value.isEmpty) - targets foreach {case (_, value) => value retain (_.exists)} - targets retain ((key, value) => key.exists && !value.isEmpty) - } - - def containsFile(f: AbstractFile) = targets.contains(f.absolute) - - def invalidatedFiles(maxDepth: Int) = { - val direct = new mutable.HashSet[AbstractFile] - - for ((file, products) <- targets) { - // This looks a bit odd. It may seem like one should invalidate a file - // if *any* of its dependencies are older than it. The forall is there - // to deal with the fact that a) Some results might have been orphaned - // and b) Some files might not need changing. - direct(file) ||= products.forall(d => d.lastModified < file.lastModified) - } - - val indirect = dependentFiles(maxDepth, direct) - - for ((source, targets) <- targets - if direct(source) || indirect(source) || (source eq removedFile)) { - targets foreach (_.delete) - targets -= source - } - - (direct, indirect) - } - - /** Return the set of files that depend on the given changed files. - * It computes the transitive closure up to the given depth. - */ - def dependentFiles(depth: Int, changed: Set[AbstractFile]): Set[AbstractFile] = { - val indirect = new mutable.HashSet[AbstractFile] - val newInvalidations = new mutable.HashSet[AbstractFile] - - def invalid(file: AbstractFile) = - indirect(file) || changed(file) || (file eq removedFile) - - def go(i: Int) : Unit = if(i > 0) { - newInvalidations.clear - for((target, depends) <- dependencies if !invalid(target); - d <- depends) - newInvalidations(target) ||= invalid(d) - - indirect ++= newInvalidations - if (!newInvalidations.isEmpty) go(i - 1) - } - - go(depth) - - indirect --= changed - } - - def writeTo(file: AbstractFile, fromFile: AbstractFile => String): Unit = - writeToFile(file)(out => writeTo(new PrintStream(out), fromFile)) - - def writeTo(print: PrintStream, fromFile: AbstractFile => String): Unit = { - def emit(tracker: Tracker) = - for ((f, ds) <- tracker; d <- ds) print.println(fromFile(f) + arrow + fromFile(d)) - - cleanEmpty - print.println(classpath) - print.println(separator) - emit(dependencies) - print.println(separator) - emit(targets) - } - } - - object FileDependencies { - private val separator:String = "-------" - private val arrow = " -> " - private val removedFile = new VirtualFile("removed") - - private def validLine(l: String) = (l != null) && (l != separator) - - def readFrom(file: AbstractFile, toFile: String => AbstractFile): Option[FileDependencies] = - readFromFile(file) { in => - val reader = new BufferedReader(new InputStreamReader(in)) - val it = new FileDependencies(reader.readLine) - - def readLines(valid: Boolean)(f: (AbstractFile, AbstractFile) => Unit): Boolean = { - var continue = valid - var line: String = null - while (continue && {line = reader.readLine; validLine(line)}) { - line.split(arrow) match { - case Array(from, on) => f(toFile(from), toFile(on)) - case _ => - global.inform("Parse error: Unrecognised string " + line) - continue = false - } - } - continue - } - - reader.readLine - - val dResult = readLines(true)( - (_, _) match { - case (null, _) => // fromFile is removed, it's ok - case (fromFile, null) => - // onFile is removed, should recompile fromFile - it.depends(fromFile, removedFile) - case (fromFile, onFile) => it.depends(fromFile, onFile) - }) - - readLines(dResult)( - (_, _) match { - case (null, null) => - // source and target are all removed, it's ok - case (null, targetFile) => - // source is removed, should remove relative target later - it.emits(removedFile, targetFile) - case (_, null) => - // it may has been cleaned outside, or removed during last phase - case (sourceFile, targetFile) => it.emits(sourceFile, targetFile) - }) - - Some(it) - } - } - - def writeToFile[T](file: AbstractFile)(f: OutputStream => T) : T = { - val out = file.bufferedOutput - try { - f(out) - } finally { - out.close - } - } - - def readFromFile[T](file: AbstractFile)(f: InputStream => T) : T = { - val in = file.input - try{ - f(in) - } finally { - in.close - } - } -} diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala index 5d2cc51c97..5d5d7d483c 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala @@ -170,7 +170,7 @@ trait ModelFactoryImplicitSupport { val newContext = context.makeImplicit(context.ambiguousErrors) newContext.macrosEnabled = false val newTyper = global.analyzer.newTyper(newContext) - newTyper.silent(_.typed(appliedTree, global.analyzer.EXPRmode, WildcardType), false) match { + newTyper.silent(_.typed(appliedTree, EXPRmode, WildcardType), false) match { case global.analyzer.SilentResultValue(t: Tree) => t case global.analyzer.SilentTypeError(err) => diff --git a/src/compiler/scala/tools/nsc/interactive/BuildManager.scala b/src/compiler/scala/tools/nsc/interactive/BuildManager.scala deleted file mode 100644 index 6b72eb12f8..0000000000 --- a/src/compiler/scala/tools/nsc/interactive/BuildManager.scala +++ /dev/null @@ -1,83 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2009-2013 Typesafe/Scala Solutions and LAMP/EPFL - * @author Iulian Dragos - * @author Hubert Plocinicak - */ -package scala.tools.nsc -package interactive - -import scala.collection._ -import io.AbstractFile -import scala.language.implicitConversions - -trait BuildManager { - - /** Add the given source files to the managed build process. */ - def addSourceFiles(files: Set[AbstractFile]) - - /** The given files have been modified by the user. Recompile - * them and their dependent files. - */ - def update(added: Set[AbstractFile], removed: Set[AbstractFile]) - - /** Notification that the supplied set of files is being built */ - def buildingFiles(included: Set[AbstractFile]) {} - - /** Load saved dependency information. */ - def loadFrom(file: AbstractFile, toFile: String => AbstractFile) : Boolean - - /** Save dependency information to `file`. */ - def saveTo(file: AbstractFile, fromFile: AbstractFile => String) - - def compiler: scala.tools.nsc.Global - - /** Delete classfiles derived from the supplied set of sources */ - def deleteClassfiles(sources : Set[AbstractFile]) { - val targets = compiler.dependencyAnalysis.dependencies.targets - for(source <- sources; cf <- targets(source)) - cf.delete - } -} - - -/** Simple driver for testing the build manager. It presents - * the user to a 'resident compiler' prompt. Each line is - * interpreted as a set of files that have changed. The builder - * then derives the dependent files and recompiles them. - */ -object BuildManagerTest extends EvalLoop { - - def prompt = "builder > " - - private def buildError(msg: String) { - println(msg + "\n scalac -help gives more information") - } - - def main(args: Array[String]) { - implicit def filesToSet(fs: List[String]): Set[AbstractFile] = { - def partition(s: String, r: Tuple2[List[AbstractFile], List[String]])= { - val v = AbstractFile.getFile(s) - if (v == null) (r._1, s::r._2) else (v::r._1, r._2) - } - val result = fs.foldRight((List[AbstractFile](), List[String]()))(partition) - if (!result._2.isEmpty) - Console.err.println("No such file(s): " + result._2.mkString(",")) - Set.empty ++ result._1 - } - - val settings = new Settings(buildError) - settings.Ybuildmanagerdebug.value = true - val command = new CompilerCommand(args.toList, settings) - val buildManager: BuildManager = new RefinedBuildManager(settings) - - buildManager.addSourceFiles(command.files) - - // enter resident mode - loop { line => - val args = line.split(' ').toList - val command = new CompilerCommand(args, settings) - buildManager.update(command.files, Set.empty) - } - - } -} diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala index 07ffe9e437..e3d59d83ea 100644 --- a/src/compiler/scala/tools/nsc/interactive/Global.scala +++ b/src/compiler/scala/tools/nsc/interactive/Global.scala @@ -1031,15 +1031,6 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") // ---------------- Helper classes --------------------------- - /** A transformer that replaces tree `from` with tree `to` in a given tree */ - class TreeReplacer(from: Tree, to: Tree) extends Transformer { - override def transform(t: Tree): Tree = { - if (t == from) to - else if ((t.pos includes from.pos) || t.pos.isTransparent) super.transform(t) - else t - } - } - /** The typer run */ class TyperRun extends Run { // units is always empty diff --git a/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala b/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala deleted file mode 100644 index 9873276f05..0000000000 --- a/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala +++ /dev/null @@ -1,354 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2009-2013 Typesafe/Scala Solutions and LAMP/EPFL - * @author Iulian Dragos - * @author Hubert Plocinicak - */ -package scala.tools.nsc -package interactive - -import scala.collection._ -import scala.tools.nsc.reporters.{Reporter, ConsoleReporter} -import scala.util.control.Breaks._ -import scala.tools.nsc.symtab.Flags - -import dependencies._ -import util.ClassPath -import io.AbstractFile -import scala.tools.util.PathResolver - -/** A more defined build manager, based on change sets. For each - * updated source file, it computes the set of changes to its - * definitions, then checks all dependent units to see if the - * changes require a compilation. It repeats this process until - * a fixpoint is reached. - */ -@deprecated("Use sbt incremental compilation mechanism", "2.10.0") -class RefinedBuildManager(val settings: Settings) extends Changes with BuildManager { - - class BuilderGlobal(settings: Settings, reporter : Reporter) extends scala.tools.nsc.Global(settings, reporter) { - - def this(settings: Settings) = - this(settings, new ConsoleReporter(settings)) - - override def computeInternalPhases() { - super.computeInternalPhases - phasesSet += dependencyAnalysis - } - lazy val _classpath = new NoSourcePathPathResolver(settings).result - override def classPath = _classpath.asInstanceOf[ClassPath[platform.BinaryRepr]] - // See discussion in JavaPlatForm for why we need a cast here. - - def newRun() = new Run() - } - - class NoSourcePathPathResolver(settings: Settings) extends PathResolver(settings) { - override def containers = Calculated.basis.dropRight(1).flatten.distinct - } - - protected def newCompiler(settings: Settings) = new BuilderGlobal(settings) - - val compiler = newCompiler(settings) - import compiler.{ Symbol, Type, enteringErasure } - import compiler.dependencyAnalysis.Inherited - - private case class SymWithHistory(sym: Symbol, befErasure: Type) - - /** Managed source files. */ - private val sources: mutable.Set[AbstractFile] = new mutable.HashSet[AbstractFile] - - private val definitions: mutable.Map[AbstractFile, List[SymWithHistory]] = - new mutable.HashMap[AbstractFile, List[SymWithHistory]] { - override def default(key: AbstractFile) = Nil - } - - /** External references used by source file. */ - private var references: mutable.Map[AbstractFile, immutable.Set[String]] = _ - - /** External references for inherited members */ - private var inherited: mutable.Map[AbstractFile, immutable.Set[Inherited]] = _ - - /** Reverse of definitions, used for caching */ - private val classes: mutable.Map[String, AbstractFile] = - new mutable.HashMap[String, AbstractFile] { - override def default(key: String) = null - } - - /** Add the given source files to the managed build process. */ - def addSourceFiles(files: Set[AbstractFile]) { - sources ++= files - update(files) - } - - /** Remove the given files from the managed build process. */ - def removeFiles(files: Set[AbstractFile]) { - sources --= files - deleteClassfiles(files) - update(invalidatedByRemove(files)) - } - - /** Return the set of invalidated files caused by removing the given files. - */ - private def invalidatedByRemove(files: Set[AbstractFile]): Set[AbstractFile] = { - val changes = new mutable.HashMap[Symbol, List[Change]] - for (f <- files; SymWithHistory(sym, _) <- definitions(f)) - changes += sym -> List(Removed(Class(sym.fullName))) - invalidated(files, changes) - } - - def update(added: Set[AbstractFile], removed: Set[AbstractFile]) { - sources --= removed - deleteClassfiles(removed) - update(added ++ invalidatedByRemove(removed)) - } - - /** The given files have been modified by the user. Recompile - * them and all files that depend on them. Only files that - * have been previously added as source files are recompiled. - * Files that were already compiled are taken out from the result - * of the dependency analysis. - */ - private def update(files: Set[AbstractFile]) = { - val coll: mutable.Map[AbstractFile, immutable.Set[AbstractFile]] = - mutable.HashMap[AbstractFile, immutable.Set[AbstractFile]]() - compiler.reporter.reset() - - // See if we really have corresponding symbols, not just those - // which share the name - def isCorrespondingSym(from: Symbol, to: Symbol): Boolean = - (from.hasFlag(Flags.TRAIT) == to.hasFlag(Flags.TRAIT)) && // has to run in 2.8, so no hasTraitFlag - (from.hasFlag(Flags.MODULE) == to.hasFlag(Flags.MODULE)) - - // For testing purposes only, order irrelevant for compilation - def toStringSet(set: Set[AbstractFile]): String = - set.toList sortBy (_.name) mkString("Set(", ", ", ")") - - def update0(files: Set[AbstractFile]): Unit = if (!files.isEmpty) { - deleteClassfiles(files) - val run = compiler.newRun() - if (settings.Ybuildmanagerdebug.value) - compiler.inform("compiling " + toStringSet(files)) - buildingFiles(files) - - run.compileFiles(files.toList) - if (compiler.reporter.hasErrors) { - return - } - - // Deterministic behaviour required by partest - val changesOf = new mutable.HashMap[Symbol, List[Change]] { - override def toString: String = { - val changesOrdered = - toList.map(e => { - e._1.toString + " -> " + - e._2.sortBy(_.toString).mkString("List(", ", ", ")") - }) - changesOrdered.sorted.mkString("Map(", ", ", ")") - } - } - val additionalDefs: mutable.HashSet[AbstractFile] = mutable.HashSet.empty - - val defs = compiler.dependencyAnalysis.definitions - for (src <- files) { - if (definitions(src).isEmpty) - additionalDefs ++= compiler.dependencyAnalysis. - dependencies.dependentFiles(1, mutable.Set(src)) - else { - val syms = defs(src) - for (sym <- syms) { - definitions(src).find( - s => (s.sym.fullName == sym.fullName) && - isCorrespondingSym(s.sym, sym)) match { - case Some(SymWithHistory(oldSym, info)) => - val changes = changeSet(oldSym.info, sym) - val changesErasure = enteringErasure(changeSet(info, sym)) - - changesOf(oldSym) = (changes ++ changesErasure).distinct - case _ => - // a new top level definition - changesOf(sym) = sym.parentSymbols filter (_.isSealed) map (p => - changeChangeSet(p, sym+" extends a sealed "+p)) - } - } - // Create a change for the top level classes that were removed - val removed = definitions(src) filterNot ((s:SymWithHistory) => - syms.find(_.fullName == (s.sym.fullName)) != None) - for (s <- removed) { - changesOf(s.sym) = List(removeChangeSet(s.sym)) - } - } - } - if (settings.Ybuildmanagerdebug.value) - compiler.inform("Changes: " + changesOf) - updateDefinitions(files) - val invalid = invalidated(files, changesOf, additionalDefs) - update0(checkCycles(invalid, files, coll)) - } - - update0(files) - // remove the current run in order to save some memory - compiler.dropRun() - } - - // Attempt to break the cycling reference deps as soon as possible and reduce - // the number of compilations to minimum without having too coarse grained rules - private def checkCycles(files: Set[AbstractFile], initial: Set[AbstractFile], - collect: mutable.Map[AbstractFile, immutable.Set[AbstractFile]]): - Set[AbstractFile] = { - def followChain(set: Set[AbstractFile], rest: immutable.Set[AbstractFile]): - immutable.Set[AbstractFile] = { - val deps:Set[AbstractFile] = set.flatMap( - s => collect.get(s) match { - case Some(x) => x - case _ => Set[AbstractFile]() - }) - val newDeps = deps -- rest - if (newDeps.isEmpty) rest else followChain(newDeps, rest ++ newDeps) - } - var res:Set[AbstractFile] = mutable.Set() - files.foreach( f => - if (collect contains f) { - val chain = followChain(Set(f), immutable.Set()) ++ files - chain.foreach((fc: AbstractFile) => collect += fc -> chain) - res ++= chain - } else - res += f - ) - - initial.foreach((f: AbstractFile) => collect += (f -> (collect.getOrElse(f, immutable.Set()) ++ res))) - if (res.subsetOf(initial)) Set() else res - } - - /** Return the set of source files that are invalidated by the given changes. */ - def invalidated(files: Set[AbstractFile], changesOf: scala.collection.Map[Symbol, List[Change]], - processed: Set[AbstractFile] = Set.empty): - Set[AbstractFile] = { - val buf = new mutable.HashSet[AbstractFile] - val newChangesOf = new mutable.HashMap[Symbol, List[Change]] - var directDeps = - compiler.dependencyAnalysis.dependencies.dependentFiles(1, files) - - def invalidate(file: AbstractFile, reason: String, change: Change) = { - if (settings.Ybuildmanagerdebug.value) - compiler.inform("invalidate " + file + " because " + reason + " [" + change + "]") - buf += file - directDeps -= file - for (syms <- definitions(file)) // fixes #2557 - newChangesOf(syms.sym) = List(change, parentChangeSet(syms.sym)) - break - } - - for ((oldSym, changes) <- changesOf; change <- changes) { - def checkParents(cls: Symbol, file: AbstractFile) { - val parentChange = cls.parentSymbols exists (_.fullName == oldSym.fullName) - // if (settings.buildmanagerdebug.value) - // compiler.inform("checkParents " + cls + " oldSym: " + oldSym + " parentChange: " + parentChange + " " + cls.info.parents) - change match { - case Changed(Class(_)) if parentChange => - invalidate(file, "parents have changed", change) - - case Changed(Definition(_)) if parentChange => - invalidate(file, "inherited method changed", change) - - case Added(Definition(_)) if parentChange => - invalidate(file, "inherited new method", change) - - case Removed(Definition(_)) if parentChange => - invalidate(file, "inherited method removed", change) - - case _ => () - } - } - - def checkInterface(cls: Symbol, file: AbstractFile) { - change match { - case Added(Definition(name)) => - if (cls.info.decls.iterator.exists(_.fullName == name)) - invalidate(file, "of new method with existing name", change) - case Changed(Class(name)) => - if (cls.info.typeSymbol.fullName == name) - invalidate(file, "self type changed", change) - case _ => - () - } - } - - def checkReferences(file: AbstractFile) { - //if (settings.buildmanagerdebug.value) - // compiler.inform(file + ":" + references(file)) - val refs = references(file) - if (refs.isEmpty) - invalidate(file, "it is a direct dependency and we don't yet have finer-grained dependency information", change) - else { - change match { - case Removed(Definition(name)) if refs(name) => - invalidate(file, "it references deleted definition", change) - case Removed(Class(name)) if (refs(name)) => - invalidate(file, "it references deleted class", change) - case Changed(Class(name)) if (refs(name)) => - invalidate(file, "it references changed class", change) - case Changed(Definition(name)) if (refs(name)) => - invalidate(file, "it references changed definition", change) - case Added(Definition(name)) if (refs(name)) => - invalidate(file, "it references added definition", change) - case _ => () - } - } - } - - def checkInheritedReferences(file: AbstractFile) { - val refs = inherited(file) - if (!refs.isEmpty) - change match { - case ParentChanged(Class(name)) => - for (Inherited(q, member) <- refs.find(p => (p != null && p.qualifier == name)); - classFile <- classes.get(q); - defs <- definitions.get(classFile); - s <- defs.find(p => p.sym.fullName == q) - if ((s.sym).tpe.nonPrivateMember(member) == compiler.NoSymbol)) - invalidate(file, "it references invalid (no longer inherited) definition", change) - () - case _ => () - } - } - - for (file <- directDeps) { - breakable { - for (cls <- definitions(file)) checkParents(cls.sym, file) - for (cls <- definitions(file)) checkInterface(cls.sym, file) - checkReferences(file) - checkInheritedReferences(file) - } - } - } - if (buf.isEmpty) - processed - else - invalidated(buf.clone() --= processed, newChangesOf, processed ++ buf) - } - - /** Update the map of definitions per source file */ - private def updateDefinitions(files: Set[AbstractFile]) { - for (src <- files; localDefs = compiler.dependencyAnalysis.definitions(src)) { - definitions(src) = (localDefs map (s => { - this.classes += s.fullName -> src - SymWithHistory(s.cloneSymbol, enteringErasure(s.info.cloneInfo(s))) - })) - } - this.references = compiler.dependencyAnalysis.references - this.inherited = compiler.dependencyAnalysis.inherited - } - - /** Load saved dependency information. */ - def loadFrom(file: AbstractFile, toFile: String => AbstractFile) : Boolean = { - val success = compiler.dependencyAnalysis.loadFrom(file, toFile) - if (success) - sources ++= compiler.dependencyAnalysis.managedFiles - success - } - - /** Save dependency information to `file`. */ - def saveTo(file: AbstractFile, fromFile: AbstractFile => String) { - compiler.dependencyAnalysis.dependenciesFile = file - compiler.dependencyAnalysis.saveDependencies(fromFile) - } -} diff --git a/src/compiler/scala/tools/nsc/interactive/SimpleBuildManager.scala b/src/compiler/scala/tools/nsc/interactive/SimpleBuildManager.scala deleted file mode 100644 index ff25dac7ac..0000000000 --- a/src/compiler/scala/tools/nsc/interactive/SimpleBuildManager.scala +++ /dev/null @@ -1,100 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2009-2013 Typesafe/Scala Solutions and LAMP/EPFL - * @author Martin Odersky - */ -package scala.tools.nsc -package interactive - -import scala.collection._ - -import scala.tools.nsc.reporters.{Reporter, ConsoleReporter} -import io.AbstractFile - -/** A simple build manager, using the default scalac dependency tracker. - * The transitive closure of all dependent files on a modified file - * is recompiled at once. - * - * It is equivalent to using a resident compiler mode with the - * '-make:transitive' option. - */ -class SimpleBuildManager(val settings: Settings) extends BuildManager { - - class BuilderGlobal(settings: Settings, reporter : Reporter) extends scala.tools.nsc.Global(settings, reporter) { - - def this(settings: Settings) = - this(settings, new ConsoleReporter(settings)) - - def newRun() = new Run() - } - - protected def newCompiler(settings: Settings) = new BuilderGlobal(settings) - - val compiler = newCompiler(settings) - - /** Managed source files. */ - private val sources: mutable.Set[AbstractFile] = new mutable.HashSet[AbstractFile] - - /** Add the given source files to the managed build process. */ - def addSourceFiles(files: Set[AbstractFile]) { - sources ++= files - update(files) - } - - /** Remove the given files from the managed build process. */ - def removeFiles(files: Set[AbstractFile]) { - sources --= files - deleteClassfiles(files) - update(invalidatedByRemove(files)) - } - - - /** Return the set of invalidated files caused by removing the given files. */ - private def invalidatedByRemove(files: Set[AbstractFile]): Set[AbstractFile] = { - val deps = compiler.dependencyAnalysis.dependencies - deps.dependentFiles(Int.MaxValue, files) - } - - def update(added: Set[AbstractFile], removed: Set[AbstractFile]) { - sources --= removed - deleteClassfiles(removed) - update(added ++ invalidatedByRemove(removed)) - } - - /** The given files have been modified by the user. Recompile - * them and all files that depend on them. Only files that - * have been previously added as source files are recompiled. - */ - def update(files: Set[AbstractFile]) { - deleteClassfiles(files) - - val deps = compiler.dependencyAnalysis.dependencies - val run = compiler.newRun() - compiler.inform("compiling " + files) - - val toCompile = - (files ++ deps.dependentFiles(Int.MaxValue, files)) intersect sources - - - compiler.inform("Recompiling " + - (if(settings.debug.value) toCompile.mkString(", ") - else toCompile.size + " files")) - - buildingFiles(toCompile) - - run.compileFiles(files.toList) - } - - /** Load saved dependency information. */ - def loadFrom(file: AbstractFile, toFile: String => AbstractFile) : Boolean = { - val success = compiler.dependencyAnalysis.loadFrom(file, toFile) - if (success) - sources ++= compiler.dependencyAnalysis.managedFiles - success - } - - /** Save dependency information to `file`. */ - def saveTo(file: AbstractFile, fromFile: AbstractFile => String) { - compiler.dependencyAnalysis.dependenciesFile = file - compiler.dependencyAnalysis.saveDependencies(fromFile) - } -} diff --git a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala index 5b0705a39e..84a47311e2 100644 --- a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala +++ b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala @@ -48,16 +48,19 @@ trait MemberHandlers { } } + private def isTermMacro(ddef: DefDef): Boolean = ddef.mods.isMacro + def chooseHandler(member: Tree): MemberHandler = member match { - case member: DefDef => new DefHandler(member) - case member: ValDef => new ValHandler(member) - case member: ModuleDef => new ModuleHandler(member) - case member: ClassDef => new ClassHandler(member) - case member: TypeDef => new TypeAliasHandler(member) - case member: Assign => new AssignHandler(member) - case member: Import => new ImportHandler(member) - case DocDef(_, documented) => chooseHandler(documented) - case member => new GenericHandler(member) + case member: DefDef if isTermMacro(member) => new TermMacroHandler(member) + case member: DefDef => new DefHandler(member) + case member: ValDef => new ValHandler(member) + case member: ModuleDef => new ModuleHandler(member) + case member: ClassDef => new ClassHandler(member) + case member: TypeDef => new TypeAliasHandler(member) + case member: Assign => new AssignHandler(member) + case member: Import => new ImportHandler(member) + case DocDef(_, documented) => chooseHandler(documented) + case member => new GenericHandler(member) } sealed abstract class MemberDefHandler(override val member: MemberDef) extends MemberHandler(member) { @@ -122,14 +125,23 @@ trait MemberHandlers { } class DefHandler(member: DefDef) extends MemberDefHandler(member) { - private def vparamss = member.vparamss - private def isMacro = member.symbol hasFlag MACRO - // true if not a macro and 0-arity - override def definesValue = !isMacro && flattensToEmpty(vparamss) + override def definesValue = flattensToEmpty(member.vparamss) // true if 0-arity override def resultExtractionCode(req: Request) = if (mods.isPublic) codegenln(name, ": ", req.typeOf(name)) else "" } + abstract class MacroHandler(member: DefDef) extends MemberDefHandler(member) { + override def definesValue = false + override def definesTerm: Option[TermName] = Some(name.toTermName) + override def definesType: Option[TypeName] = None + override def resultExtractionCode(req: Request) = if (mods.isPublic) codegenln(notification(req)) else "" + def notification(req: Request): String + } + + class TermMacroHandler(member: DefDef) extends MacroHandler(member) { + def notification(req: Request) = s"defined term macro $name: ${req.typeOf(name)}" + } + class AssignHandler(member: Assign) extends MemberHandler(member) { val Assign(lhs, rhs) = member override lazy val name = newTermName(freshInternalVarName()) diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplGlobal.scala b/src/compiler/scala/tools/nsc/interpreter/ReplGlobal.scala index 16b22869e7..0eabd84234 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ReplGlobal.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ReplGlobal.scala @@ -24,7 +24,7 @@ trait ReplGlobal extends Global { val global: ReplGlobal.this.type = ReplGlobal.this } with Analyzer { override def newTyper(context: Context): Typer = new Typer(context) { - override def typed(tree: Tree, mode: Int, pt: Type): Tree = { + override def typed(tree: Tree, mode: Mode, pt: Type): Tree = { val res = super.typed(tree, mode, pt) tree match { case Ident(name) if !tree.symbol.hasPackageFlag && !name.toString.startsWith("$") => diff --git a/src/compiler/scala/tools/nsc/package.scala b/src/compiler/scala/tools/nsc/package.scala index 940df1bd1a..ee1668a38a 100644 --- a/src/compiler/scala/tools/nsc/package.scala +++ b/src/compiler/scala/tools/nsc/package.scala @@ -6,6 +6,15 @@ package scala.tools package object nsc { + type Mode = scala.reflect.internal.Mode + val Mode = scala.reflect.internal.Mode + + def EXPRmode = Mode.EXPRmode + def BYVALmode = Mode.BYVALmode + def POLYmode = Mode.POLYmode + def TAPPmode = Mode.TAPPmode + def FUNmode = Mode.FUNmode + type Phase = scala.reflect.internal.Phase val NoPhase = scala.reflect.internal.NoPhase diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 9c8ffc5ae3..36e6a74820 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -162,7 +162,6 @@ trait ScalaSettings extends AbsScalaSettings val refinementMethodDispatch = ChoiceSetting ("-Ystruct-dispatch", "policy", "structural method dispatch policy", List("no-cache", "mono-cache", "poly-cache", "invoke-dynamic"), "poly-cache") val Yrangepos = BooleanSetting ("-Yrangepos", "Use range positions for syntax trees.") - val Ybuilderdebug = ChoiceSetting ("-Ybuilder-debug", "manager", "Compile using the specified build manager.", List("none", "refined", "simple"), "none") val Yreifycopypaste = BooleanSetting ("-Yreify-copypaste", "Dump the reified trees in copypasteable representation.") val Yreplsync = BooleanSetting ("-Yrepl-sync", "Do not use asynchronous code for repl startup") val Yreploutdir = StringSetting ("-Yrepl-outdir", "path", "Write repl-generated classfiles to given output directory (use \"\" to generate a temporary dir)" , "") @@ -177,7 +176,6 @@ trait ScalaSettings extends AbsScalaSettings /** Area-specific debug output. */ - val Ybuildmanagerdebug = BooleanSetting("-Ybuild-manager-debug", "Generate debug information for the Refined Build Manager compiler.") val Ydocdebug = BooleanSetting("-Ydoc-debug", "Trace all scaladoc activity.") val Yidedebug = BooleanSetting("-Yide-debug", "Generate, validate and output trees using the interactive compiler.") val Yinferdebug = BooleanSetting("-Yinfer-debug", "Trace type inference and implicit search.") diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index efe7519d5e..c8b7fcee8f 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -77,11 +77,7 @@ abstract class Pickler extends SubComponent { } if (!t.isDef && t.hasSymbolField && t.symbol.isTermMacro) { - unit.error(t.pos, t.symbol.typeParams.length match { - case 0 => "macro has not been expanded" - case 1 => "this type parameter must be specified" - case _ => "these type parameters must be specified" - }) + unit.error(t.pos, "macro has not been expanded") return } } diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 13d3bb23cb..e3b5efde1f 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -10,6 +10,7 @@ import scala.reflect.internal.ClassfileConstants._ import scala.collection.{ mutable, immutable } import symtab._ import Flags._ +import scala.reflect.internal.Mode._ abstract class Erasure extends AddInterfaces with scala.reflect.internal.transform.Erasure @@ -801,12 +802,12 @@ abstract class Erasure extends AddInterfaces /** A replacement for the standard typer's adapt method. */ - override protected def adapt(tree: Tree, mode: Int, pt: Type, original: Tree = EmptyTree): Tree = + override protected def adapt(tree: Tree, mode: Mode, pt: Type, original: Tree = EmptyTree): Tree = adaptToType(tree, pt) /** A replacement for the standard typer's `typed1` method. */ - override def typed1(tree: Tree, mode: Int, pt: Type): Tree = { + override def typed1(tree: Tree, mode: Mode, pt: Type): Tree = { val tree1 = try { tree match { case InjectDerivedValue(arg) => diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index 0769b67282..6a253a98b1 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -1089,7 +1089,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { // add forwarders assert(sym.alias != NoSymbol, sym) // debuglog("New forwarder: " + sym.defString + " => " + sym.alias.defString) - if (!sym.isTermMacro) addDefDef(sym, Apply(staticRef(sym.alias), gen.mkAttributedThis(clazz) :: sym.paramss.head.map(Ident))) + if (!sym.isMacro) addDefDef(sym, Apply(staticRef(sym.alias), gen.mkAttributedThis(clazz) :: sym.paramss.head.map(Ident))) } } } diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index ea03aca8c4..2d4054e93b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -562,11 +562,13 @@ trait ContextErrors { //adapt def MissingArgsForMethodTpeError(tree: Tree, meth: Symbol) = { - issueNormalTypeError(tree, - "missing arguments for " + meth.fullLocationString + ( + val message = + if (meth.isMacro) MacroPartialApplicationErrorMessage + else "missing arguments for " + meth.fullLocationString + ( if (meth.isConstructor) "" else ";\nfollow this method with `_' if you want to treat it as a partially applied function" - )) + ) + issueNormalTypeError(tree, message) setError(tree) } @@ -670,6 +672,14 @@ trait ContextErrors { setError(tree) } + def MacroTooManyArgumentListsError(expandee: Tree, fun: Symbol) = { + NormalTypeError(expandee, "too many argument lists for " + fun) + } + + def MacroInvalidExpansionError(expandee: Tree, role: String, allowedExpansions: String) = { + issueNormalTypeError(expandee, s"macro in $role role can only expand into $allowedExpansions") + } + // same reason as for MacroBodyTypecheckException case object MacroExpansionException extends Exception with scala.util.control.ControlThrowable @@ -681,10 +691,11 @@ trait ContextErrors { throw MacroExpansionException } + def MacroPartialApplicationErrorMessage = "macros cannot be partially applied" def MacroPartialApplicationError(expandee: Tree) = { // macroExpansionError won't work => swallows positions, hence needed to do issueTypeError // kinda contradictory to the comment in `macroExpansionError`, but this is how it works - issueNormalTypeError(expandee, "macros cannot be partially applied") + issueNormalTypeError(expandee, MacroPartialApplicationErrorMessage) setError(expandee) throw MacroExpansionException } @@ -750,13 +761,16 @@ trait ContextErrors { macroExpansionError(expandee, template(sym.name.nameKind).format(sym.name + " " + sym.origin, forgotten)) } - def MacroExpansionIsNotExprError(expandee: Tree, expanded: Any) = + def MacroExpansionHasInvalidTypeError(expandee: Tree, expanded: Any) = { + val expected = "expr" + val isPathMismatch = expanded != null && expanded.isInstanceOf[scala.reflect.api.Exprs#Expr[_]] macroExpansionError(expandee, - "macro must return a compiler-specific expr; returned value is " + ( + s"macro must return a compiler-specific $expected; returned value is " + ( if (expanded == null) "null" - else if (expanded.isInstanceOf[Expr[_]]) " Expr, but it doesn't belong to this compiler's universe" + else if (isPathMismatch) s" $expected, but it doesn't belong to this compiler" else " of " + expanded.getClass )) + } def MacroImplementationNotFoundError(expandee: Tree) = macroExpansionError(expandee, diff --git a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala index 1c48eeed70..ab65e18093 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala @@ -197,7 +197,7 @@ abstract class Duplicators extends Analyzer { * their symbols are recreated ad-hoc and their types are fixed inline, instead of letting the * namer/typer handle them, or Idents that refer to them. */ - override def typed(tree: Tree, mode: Int, pt: Type): Tree = { + override def typed(tree: Tree, mode: Mode, pt: Type): Tree = { debuglog("typing " + tree + ": " + tree.tpe + ", " + tree.getClass) val origtreesym = tree.symbol if (tree.hasSymbolField && tree.symbol != NoSymbol diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index ed1e6d01e8..e435717839 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -668,7 +668,11 @@ trait Implicits { // duplicating the code here, but this is probably a // hotspot (and you can't just call typed, need to force // re-typecheck) - val checked = itree2 match { + // + // This is just called for the side effect of error detection, + // see SI-6966 to see what goes wrong if we use the result of this + // as the SearchResult. + itree2 match { case TypeApply(fun, args) => typedTypeApply(itree2, EXPRmode, fun, args) case Apply(TypeApply(fun, args), _) => typedTypeApply(itree2, EXPRmode, fun, args) // t2421c case t => t @@ -677,7 +681,7 @@ trait Implicits { if (context.hasErrors) fail("typing TypeApply reported errors for the implicit tree: " + context.errBuffer.head.errMsg) else { - val result = new SearchResult(checked, subst) + val result = new SearchResult(itree2, subst) if (Statistics.canEnable) Statistics.incCounter(foundImplicits) printInference("[success] found %s for pt %s".format(result, ptInstantiated)) result diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 768d739b4b..5b27fd9352 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -5,6 +5,7 @@ import symtab.Flags._ import scala.tools.nsc.util._ import scala.reflect.runtime.ReflectionUtils import scala.collection.mutable.ListBuffer +import scala.reflect.ClassTag import scala.reflect.internal.util.Statistics import scala.reflect.macros.util._ import scala.util.control.ControlThrowable @@ -357,7 +358,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { // Phase I: sanity checks val macroDef = macroDdef.symbol macroLogVerbose("typechecking macro def %s at %s".format(macroDef, macroDdef.pos)) - assert(macroDef.isTermMacro, macroDdef) + assert(macroDef.isMacro, macroDdef) if (fastTrack contains macroDef) MacroDefIsFastTrack() if (!typer.checkFeature(macroDdef.pos, MacrosFeature, immediate = true)) MacroFeatureNotEnabled() @@ -372,7 +373,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { // doesn't manifest itself as an error in the resulting tree val prevNumErrors = reporter.ERROR.count var rhs1 = typer.typed1(rhs, EXPRmode, WildcardType) - def rhsNeedsMacroExpansion = rhs1.symbol != null && rhs1.symbol.isTermMacro && !rhs1.symbol.isErroneous + def rhsNeedsMacroExpansion = rhs1.symbol != null && rhs1.symbol.isMacro && !rhs1.symbol.isErroneous while (rhsNeedsMacroExpansion) { rhs1 = macroExpand1(typer, rhs1) match { case Success(expanded) => @@ -385,8 +386,12 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { } case Fallback(fallback) => typer.typed1(fallback, EXPRmode, WildcardType) - case Other(result) => - result + case Delayed(delayed) => + delayed + case Skipped(skipped) => + skipped + case Failure(failure) => + failure } } val typecheckedWithErrors = (rhs1 exists (_.isErroneous)) || reporter.ERROR.count != prevNumErrors @@ -533,15 +538,17 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { } } - private def macroContext(typer: Typer, prefixTree: Tree, expandeeTree: Tree): MacroContext = + private def macroContext(typer: Typer, prefixTree: Tree, expandeeTree: Tree): MacroContext = { new { val universe: self.global.type = self.global val callsiteTyper: universe.analyzer.Typer = typer.asInstanceOf[global.analyzer.Typer] - val expandee = expandeeTree + val expandee = universe.analyzer.macroExpanderAttachment(expandeeTree).original orElse expandeeTree + val macroRole = universe.analyzer.macroExpanderAttachment(expandeeTree).role } with UnaffiliatedMacroContext { val prefix = Expr[Nothing](prefixTree)(TypeTag.Nothing) override def toString = "MacroContext(%s@%s +%d)".format(expandee.symbol.name, expandee.pos, enclosingMacros.length - 1 /* exclude myself */) } + } /** Calculate the arguments to pass to a macro implementation when expanding the provided tree. */ @@ -645,21 +652,37 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { private def popMacroContext() = _openMacros = _openMacros.tail def enclosingMacroPosition = openMacros map (_.macroApplication.pos) find (_ ne NoPosition) getOrElse NoPosition - private sealed abstract class MacroExpansionResult - private case class Success(expanded: Tree) extends MacroExpansionResult - private case class Fallback(fallback: Tree) extends MacroExpansionResult { currentRun.seenMacroExpansionsFallingBack = true } - private case class Other(result: Tree) extends MacroExpansionResult - private def Delay(expanded: Tree) = Other(expanded) - private def Skip(expanded: Tree) = Other(expanded) - private def Cancel(expandee: Tree) = Other(expandee) - private def Failure(expandee: Tree) = Other(expandee) + /** Describes the role that the macro expandee is performing. + */ + type MacroRole = String + final def APPLY_ROLE: MacroRole = "APPLY_ROLE" + private val roleNames = Map(APPLY_ROLE -> "apply") /** Performs macro expansion: - * 1) Checks whether the expansion needs to be delayed (see `mustDelayMacroExpansion`) - * 2) Loads macro implementation using `macroMirror` - * 3) Synthesizes invocation arguments for the macro implementation - * 4) Checks that the result is a tree bound to this universe - * 5) Typechecks the result against the return type of the macro definition + * + * ========= Expandable trees ========= + * + * A term of one of the following shapes: + * + * Ident(<term macro>) + * Select(<any qualifier>, <term macro>) + * TypeApply(<any of the above>, <targs>) + * Apply(...Apply(<any of the above>, <args1>)...<argsN>) + * + * ========= Macro expansion ========= + * + * First of all `macroExpandXXX`: + * 1) If necessary desugars the `expandee` to fit into `macroExpand1` + * + * Then `macroExpand1`: + * 2) Checks whether the expansion needs to be delayed (see `mustDelayMacroExpansion`) + * 3) Loads macro implementation using `macroMirror` + * 4) Synthesizes invocation arguments for the macro implementation + * 5) Checks that the result is a tree or an expr bound to this universe + * + * Finally `macroExpandXXX`: + * 6) Validates the expansion against the white list of supported tree shapes + * 7) Typechecks the result as required by the circumstances of the macro application * * If -Ymacro-debug-lite is enabled, you will get basic notifications about macro expansion * along with macro expansions logged in the form that can be copy/pasted verbatim into REPL. @@ -670,52 +693,118 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { * * @return * the expansion result if the expansion has been successful, - * the fallback method invocation if the expansion has been unsuccessful, but there is a fallback, + * the fallback tree if the expansion has been unsuccessful, but there is a fallback, * the expandee unchanged if the expansion has been delayed, * the expandee fully expanded if the expansion has been delayed before and has been expanded now, * the expandee with an error marker set if the expansion has been cancelled due malformed arguments or implementation * the expandee with an error marker set if there has been an error */ - def macroExpand(typer: Typer, expandee: Tree, mode: Int = EXPRmode, pt: Type = WildcardType): Tree = { - val start = if (Statistics.canEnable) Statistics.startTimer(macroExpandNanos) else null - if (Statistics.canEnable) Statistics.incCounter(macroExpandCount) - try { - macroExpand1(typer, expandee) match { - case Success(expanded) => - try { - def typecheck(phase: String, tree: Tree, pt: Type): Tree = { - if (tree.isErroneous) return tree - macroLogVerbose(s"typechecking against $phase $pt: $expanded") - val numErrors = reporter.ERROR.count - def hasNewErrors = reporter.ERROR.count > numErrors - val result = typer.context.withImplicitsEnabled(typer.typed(tree, EXPRmode, pt)) - macroTraceVerbose(s"""${if (hasNewErrors) "failed to typecheck" else "successfully typechecked"} against $phase $pt:\n$result\n""")(result) + private abstract class MacroExpander[Result: ClassTag](val role: MacroRole, val typer: Typer, val expandee: Tree) { + def allowExpandee(expandee: Tree): Boolean = true + def allowExpanded(expanded: Tree): Boolean = true + def allowedExpansions: String = "anything" + def allowResult(result: Result): Boolean = true + + def onSuccess(expanded: Tree): Result + def onFallback(expanded: Tree): Result + def onSuppressed(expandee: Tree): Result = expandee match { case expandee: Result => expandee } + def onDelayed(expanded: Tree): Result = expanded match { case expanded: Result => expanded } + def onSkipped(expanded: Tree): Result = expanded match { case expanded: Result => expanded } + def onFailure(expanded: Tree): Result = { typer.infer.setError(expandee); expandee match { case expandee: Result => expandee } } + + def apply(desugared: Tree): Result = { + if (isMacroExpansionSuppressed(desugared)) onSuppressed(expandee) + else expand(desugared) + } + + protected def expand(desugared: Tree): Result = { + def showDetailed(tree: Tree) = showRaw(tree, printIds = true, printTypes = true) + def summary() = s"expander = $this, expandee = ${showDetailed(expandee)}, desugared = ${if (expandee == desugared) () else showDetailed(desugared)}" + if (macroDebugVerbose) println(s"macroExpand: ${summary()}") + assert(allowExpandee(expandee), summary()) + + val start = if (Statistics.canEnable) Statistics.startTimer(macroExpandNanos) else null + if (Statistics.canEnable) Statistics.incCounter(macroExpandCount) + try { + linkExpandeeAndDesugared(expandee, desugared, role) + macroExpand1(typer, desugared) match { + case Success(expanded) => + if (allowExpanded(expanded)) { + // also see http://groups.google.com/group/scala-internals/browse_thread/thread/492560d941b315cc + val expanded1 = try onSuccess(duplicateAndKeepPositions(expanded)) finally popMacroContext() + if (!hasMacroExpansionAttachment(expanded1)) linkExpandeeAndExpanded(expandee, expanded1) + if (allowResult(expanded1)) expanded1 else onFailure(expanded) + } else { + typer.TyperErrorGen.MacroInvalidExpansionError(expandee, roleNames(role), allowedExpansions) + onFailure(expanded) } + case Fallback(fallback) => onFallback(fallback) + case Delayed(delayed) => onDelayed(delayed) + case Skipped(skipped) => onSkipped(skipped) + case Failure(failure) => onFailure(failure) + } + } finally { + if (Statistics.canEnable) Statistics.stopTimer(macroExpandNanos, start) + } + } + } - var expectedTpe = expandee.tpe - if (isNullaryInvocation(expandee)) expectedTpe = expectedTpe.finalResultType - // also see http://groups.google.com/group/scala-internals/browse_thread/thread/492560d941b315cc - val expanded0 = duplicateAndKeepPositions(expanded) - val expanded1 = typecheck("macro def return type", expanded0, expectedTpe) - val expanded2 = typecheck("expected type", expanded1, pt) - expanded2 - } finally { - popMacroContext() - } - case Fallback(fallback) => - typer.context.withImplicitsEnabled(typer.typed(fallback, EXPRmode, pt)) - case Other(result) => - result + /** Expands a tree that carries a term, which happens to be a term macro. + * @see MacroExpander + */ + private abstract class TermMacroExpander(role: MacroRole, typer: Typer, expandee: Tree, mode: Mode, pt: Type) + extends MacroExpander[Tree](role, typer, expandee) { + override def allowedExpansions: String = "term trees" + override def allowExpandee(expandee: Tree) = expandee.isTerm + override def onSuccess(expanded: Tree) = typer.typed(expanded, mode, pt) + override def onFallback(fallback: Tree) = typer.typed(fallback, mode, pt) + } + + /** Expands a term macro used in apply role as `M(2)(3)` in `val x = M(2)(3)`. + * @see MacroExpander + */ + def macroExpandApply(typer: Typer, expandee: Tree, mode: Mode, pt: Type) = { + object expander extends TermMacroExpander(APPLY_ROLE, typer, expandee, mode, pt) { + override def onSuccess(expanded: Tree) = { + // prematurely annotate the tree with a macro expansion attachment + // so that adapt called indirectly by typer.typed knows that it needs to apply the existential fixup + linkExpandeeAndExpanded(expandee, expanded) + var expectedTpe = expandee.tpe + if (isNullaryInvocation(expandee)) expectedTpe = expectedTpe.finalResultType + // `macroExpandApply` is called from `adapt`, where implicit conversions are disabled + // therefore we need to re-enable the conversions back temporarily + if (macroDebugVerbose) println(s"typecheck #1 (against expectedTpe = $expectedTpe): $expanded") + val expanded1 = typer.context.withImplicitsEnabled(typer.typed(expanded, mode, expectedTpe)) + if (expanded1.isErrorTyped) { + if (macroDebugVerbose) println(s"typecheck #1 has failed: ${typer.context.errBuffer}") + expanded1 + } else { + if (macroDebugVerbose) println(s"typecheck #2 (against pt = $pt): $expanded1") + val expanded2 = typer.context.withImplicitsEnabled(super.onSuccess(expanded1)) + if (macroDebugVerbose && expanded2.isErrorTyped) println(s"typecheck #2 has failed: ${typer.context.errBuffer}") + expanded2 + } } - } finally { - if (Statistics.canEnable) Statistics.stopTimer(macroExpandNanos, start) } + expander(expandee) } + /** Captures statuses of macro expansions performed by `macroExpand1'. + */ + private sealed abstract class MacroStatus(val result: Tree) + private case class Success(expanded: Tree) extends MacroStatus(expanded) + private case class Fallback(fallback: Tree) extends MacroStatus(fallback) { currentRun.seenMacroExpansionsFallingBack = true } + private case class Delayed(delayed: Tree) extends MacroStatus(delayed) + private case class Skipped(skipped: Tree) extends MacroStatus(skipped) + private case class Failure(failure: Tree) extends MacroStatus(failure) + private def Delay(expanded: Tree) = Delayed(expanded) + private def Skip(expanded: Tree) = Skipped(expanded) + private def Cancel(expandee: Tree) = Failure(expandee) + /** Does the same as `macroExpand`, but without typechecking the expansion * Meant for internal use within the macro infrastructure, don't use it elsewhere. */ - private def macroExpand1(typer: Typer, expandee: Tree): MacroExpansionResult = { + private def macroExpand1(typer: Typer, expandee: Tree): MacroStatus = { // verbose printing might cause recursive macro expansions, so I'm shutting it down here withInfoLevel(nodePrinters.InfoLevel.Quiet) { if (expandee.symbol.isErroneous || (expandee exists (_.isErroneous))) { @@ -736,14 +825,18 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { /** Expands a macro when a runtime (i.e. the macro implementation) can be successfully loaded * Meant for internal use within the macro infrastructure, don't use it elsewhere. */ - private def macroExpandWithRuntime(typer: Typer, expandee: Tree, runtime: MacroRuntime): MacroExpansionResult = { + private def macroExpandWithRuntime(typer: Typer, expandee: Tree, runtime: MacroRuntime): MacroStatus = { val wasDelayed = isDelayed(expandee) val undetparams = calculateUndetparams(expandee) val nowDelayed = !typer.context.macrosEnabled || undetparams.nonEmpty (wasDelayed, nowDelayed) match { - case (true, true) => Delay(expandee) - case (true, false) => Skip(macroExpandAll(typer, expandee)) + case (true, true) => + Delay(expandee) + case (true, false) => + val expanded = macroExpandAll(typer, expandee) + if (expanded exists (_.isErroneous)) Failure(expandee) + else Skip(expanded) case (false, true) => macroLogLite("macro expansion is delayed: %s".format(expandee)) delayed += expandee -> undetparams @@ -758,15 +851,16 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { def hasNewErrors = reporter.ERROR.count > numErrors val expanded = { pushMacroContext(args.c); runtime(args) } if (hasNewErrors) MacroGeneratedTypeError(expandee) + def validateResultingTree(expanded: Tree) = { + macroLogVerbose("original:") + macroLogLite("" + expanded + "\n" + showRaw(expanded)) + val freeSyms = expanded.freeTerms ++ expanded.freeTypes + freeSyms foreach (sym => MacroFreeSymbolError(expandee, sym)) + Success(atPos(enclosingMacroPosition.focus)(expanded)) + } expanded match { - case expanded: Expr[_] => - macroLogVerbose("original:") - macroLogLite("" + expanded.tree + "\n" + showRaw(expanded.tree)) - val freeSyms = expanded.tree.freeTerms ++ expanded.tree.freeTypes - freeSyms foreach (sym => MacroFreeSymbolError(expandee, sym)) - Success(atPos(enclosingMacroPosition.focus)(expanded.tree updateAttachment MacroExpansionAttachment(expandee))) - case _ => - MacroExpansionIsNotExprError(expandee, expanded) + case expanded: Expr[_] if expandee.symbol.isTermMacro => validateResultingTree(expanded.tree) + case _ => MacroExpansionHasInvalidTypeError(expandee, expanded) } } catch { case ex: Throwable => @@ -787,7 +881,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { /** Expands a macro when a runtime (i.e. the macro implementation) cannot be loaded * Meant for internal use within the macro infrastructure, don't use it elsewhere. */ - private def macroExpandWithoutRuntime(typer: Typer, expandee: Tree): MacroExpansionResult = { + private def macroExpandWithoutRuntime(typer: Typer, expandee: Tree): MacroStatus = { import typer.TyperErrorGen._ val fallbackSym = expandee.symbol.nextOverriddenSymbol orElse MacroImplementationNotFoundError(expandee) macroTraceLite("falling back to: ")(fallbackSym) @@ -857,13 +951,13 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { new Transformer { override def transform(tree: Tree) = super.transform(tree match { // todo. expansion should work from the inside out - case tree if (delayed contains tree) && calculateUndetparams(tree).isEmpty => + case tree if (delayed contains tree) && calculateUndetparams(tree).isEmpty && !tree.isErroneous => val context = tree.attachments.get[MacroRuntimeAttachment].get.typerContext delayed -= tree context.implicitsEnabled = typer.context.implicitsEnabled context.enrichmentEnabled = typer.context.enrichmentEnabled context.macrosEnabled = typer.context.macrosEnabled - macroExpand(newTyper(context), tree, EXPRmode, WildcardType) + macroExpandApply(newTyper(context), tree, EXPRmode, WildcardType) case _ => tree }) diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index d74d5ecfbe..b226591c8d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -126,7 +126,7 @@ trait MethodSynthesis { /** There are two key methods in here. * - * 1) Enter methods such as enterGetterSetterare called + * 1) Enter methods such as enterGetterSetter are called * from Namer with a tree which may generate further trees such as accessors or * implicit wrappers. Some setup is performed. In general this creates symbols * and enters them into the scope of the owner. @@ -171,14 +171,46 @@ trait MethodSynthesis { enterBeans(tree) } + /** This is called for those ValDefs which addDerivedTrees ignores, but + * which might have a warnable annotation situation. + */ + private def warnForDroppedAnnotations(tree: Tree) { + val annotations = tree.symbol.initialize.annotations + val targetClass = defaultAnnotationTarget(tree) + val retained = deriveAnnotations(annotations, targetClass, keepClean = true) + + annotations filterNot (retained contains _) foreach (ann => issueAnnotationWarning(tree, ann, targetClass)) + } + private def issueAnnotationWarning(tree: Tree, ann: AnnotationInfo, defaultTarget: Symbol) { + global.reporter.warning(ann.pos, + s"no valid targets for annotation on ${tree.symbol} - it is discarded unused. " + + s"You may specify targets with meta-annotations, e.g. @($ann @${defaultTarget.name})") + } + def addDerivedTrees(typer: Typer, stat: Tree): List[Tree] = stat match { case vd @ ValDef(mods, name, tpt, rhs) if !noFinishGetterSetter(vd) => // If we don't save the annotations, they seem to wander off. val annotations = stat.symbol.initialize.annotations - ( allValDefDerived(vd) + val trees = ( + allValDefDerived(vd) map (acc => atPos(vd.pos.focus)(acc derive annotations)) filterNot (_ eq EmptyTree) ) + // Verify each annotation landed safely somewhere, else warn. + // Filtering when isParamAccessor is a necessary simplification + // because there's a bunch of unwritten annotation code involving + // the propagation of annotations - constructor parameter annotations + // may need to make their way to parameters of the constructor as + // well as fields of the class, etc. + if (!mods.isParamAccessor) annotations foreach (ann => + if (!trees.exists(_.symbol hasAnnotation ann.symbol)) + issueAnnotationWarning(vd, ann, GetterTargetClass) + ) + + trees + case vd: ValDef => + warnForDroppedAnnotations(vd) + vd :: Nil case cd @ ClassDef(mods, _, _, _) if mods.isImplicit => val annotations = stat.symbol.initialize.annotations // TODO: need to shuffle annotations between wrapper and class. diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index b5160c0519..352090892e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -878,7 +878,7 @@ trait Namers extends MethodSynthesis { else tpt.tpe } - val parents = typer.parentTypes(templ) map checkParent + val parents = typer.typedParentTypes(templ) map checkParent enterSelf(templ.self) @@ -1054,7 +1054,7 @@ trait Namers extends MethodSynthesis { // because @macroImpl annotation only gets assigned during typechecking // otherwise macro defs wouldn't be able to robustly coexist with their clients // because a client could be typechecked before a macro def that it uses - if (ddef.symbol.isTermMacro) { + if (ddef.symbol.isMacro) { val pt = resultPt.substSym(tparamSyms, tparams map (_.symbol)) typer.computeMacroDefType(ddef, pt) } diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index dfc1196f2e..f5884e5c34 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -104,7 +104,7 @@ trait NamesDefaults { self: Analyzer => * @return the transformed application (a Block) together with the NamedApplyInfo. * if isNamedApplyBlock(tree), returns the existing context.namedApplyBlockInfo */ - def transformNamedApplication(typer: Typer, mode: Int, pt: Type) + def transformNamedApplication(typer: Typer, mode: Mode, pt: Type) (tree: Tree, argPos: Int => Int): Tree = { import typer._ import typer.infer._ diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala index 49eca828a9..5f70da6a63 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala @@ -3520,7 +3520,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL override def emitSwitch(scrut: Tree, scrutSym: Symbol, cases: List[List[TreeMaker]], pt: Type, matchFailGenOverride: Option[Tree => Tree], unchecked: Boolean): Option[Tree] = { import CODE._ val regularSwitchMaker = new RegularSwitchMaker(scrutSym, matchFailGenOverride, unchecked) // TODO: if patterns allow switch but the type of the scrutinee doesn't, cast (type-test) the scrutinee to the corresponding switchable type and switch on the result - if (regularSwitchMaker.switchableTpe(scrutSym.tpe)) { + if (regularSwitchMaker.switchableTpe(scrutSym.tpe.dealiasWiden)) { val caseDefsWithDefault = regularSwitchMaker(cases map {c => (scrutSym, c)}, pt) if (caseDefsWithDefault isEmpty) None // not worth emitting a switch. else { diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 8a34d58e6e..e88447c46d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -424,9 +424,9 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans member.isValue && !member.isLazy) { overrideError("must be declared lazy to override a concrete lazy value") } else if (other.isDeferred && member.isTermMacro) { // (1.9) - overrideError("cannot override an abstract method") + overrideError("cannot be used here - term macros cannot override abstract methods") } else if (other.isTermMacro && !member.isTermMacro) { // (1.10) - overrideError("cannot override a macro") + overrideError("cannot be used here - only term macros can override term macros") } else { checkOverrideTypes() checkOverrideDeprecated() diff --git a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala index 20db479463..64fcda3b80 100644 --- a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala +++ b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala @@ -14,6 +14,102 @@ trait StdAttachments { type MacroContext = UnaffiliatedMacroContext { val universe: self.global.type } case class MacroRuntimeAttachment(delayed: Boolean, typerContext: Context, macroContext: Option[MacroContext]) + /** Scratchpad for the macro expander, which is used to store all intermediate data except the details about the runtime. + */ + case class MacroExpanderAttachment(original: Tree, desugared: Tree, role: MacroRole) + + /** Loads underlying MacroExpanderAttachment from a macro expandee or returns a default value for that attachment. + */ + def macroExpanderAttachment(tree: Tree): MacroExpanderAttachment = + tree.attachments.get[MacroExpanderAttachment] getOrElse { + tree match { + case Apply(fn, _) if tree.isInstanceOf[ApplyToImplicitArgs] => macroExpanderAttachment(fn) + case _ => MacroExpanderAttachment(tree, EmptyTree, APPLY_ROLE) + } + } + + /** After macro expansion is completed, links the expandee and the expansion result + * by annotating them both with a `MacroExpansionAttachment`. + */ + def linkExpandeeAndDesugared(expandee: Tree, desugared: Tree, role: MacroRole): Unit = { + val metadata = MacroExpanderAttachment(expandee, desugared, role) + expandee updateAttachment metadata + desugared updateAttachment metadata + } + + /** Is added by the macro engine to originals and results of macro expansions. + * Stores the original expandee as it entered the `macroExpand` function. + */ + case class MacroExpansionAttachment(expandee: Tree, expanded: Any) + + /** Determines whether the target is either an original or a result of a macro expansion. + * The parameter is of type `Any`, because macros can expand both into trees and into annotations. + */ + def hasMacroExpansionAttachment(any: Any): Boolean = any match { + case tree: Tree => tree.attachments.get[MacroExpansionAttachment].isDefined + case _ => false + } + + /** After macro expansion is completed, links the expandee and the expansion result by annotating them both with a `MacroExpansionAttachment`. + * The `expanded` parameter is of type `Any`, because macros can expand both into trees and into annotations. + */ + def linkExpandeeAndExpanded(expandee: Tree, expanded: Any): Unit = { + val metadata = MacroExpansionAttachment(expandee, expanded) + expandee updateAttachment metadata + expanded match { + case expanded: Tree => expanded updateAttachment metadata + case _ => // do nothing + } + } + + /** Checks whether there is any tree resulting from a macro expansion and associated with the current tree. + */ + object ExpandedIntoTree { + def unapply(tree: Tree): Option[Tree] = tree.attachments.get[MacroExpansionAttachment] match { + case Some(MacroExpansionAttachment(_, tree: Tree)) => Some(tree) + case _ => None + } + } + + /** When present, suppresses macro expansion for the host. + * This is occasionally necessary, e.g. to prohibit eta-expansion of macros. + * + * Does not affect expandability of child nodes, there's context.withMacrosDisabled for that + * (but think thrice before using that API - see the discussion at https://github.com/scala/scala/pull/1639). + */ + case object SuppressMacroExpansionAttachment + + /** Suppresses macro expansion of the tree by putting SuppressMacroExpansionAttachment on it. + */ + def suppressMacroExpansion(tree: Tree) = tree.updateAttachment(SuppressMacroExpansionAttachment) + + /** Unsuppresses macro expansion of the tree by removing SuppressMacroExpansionAttachment from it and its children. + */ + def unsuppressMacroExpansion(tree: Tree): Tree = { + tree.removeAttachment[SuppressMacroExpansionAttachment.type] + tree match { + // see the comment to `isMacroExpansionSuppressed` to learn why we need + // a special traversal strategy here + case Apply(fn, _) => unsuppressMacroExpansion(fn) + case TypeApply(fn, _) => unsuppressMacroExpansion(fn) + case _ => // do nothing + } + tree + } + + /** Determines whether a tree should not be expanded, because someone has put SuppressMacroExpansionAttachment on it or one of its children. + */ + def isMacroExpansionSuppressed(tree: Tree): Boolean = + if (tree.attachments.get[SuppressMacroExpansionAttachment.type].isDefined) true + else tree match { + // we have to account for the fact that during typechecking an expandee might become wrapped, + // i.e. surrounded by an inferred implicit argument application or by an inferred type argument application. + // in that case the expandee itself will no longer be suppressed and we need to look at the core + case Apply(fn, _) => isMacroExpansionSuppressed(fn) + case TypeApply(fn, _) => isMacroExpansionSuppressed(fn) + case _ => false + } + /** After being synthesized by the parser, primary constructors aren't fully baked yet. * A call to super in such constructors is just a fill-me-in-later dummy resolved later * by `parentTypes`. This attachment coordinates `parentTypes` and `typedTemplate` and diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala index 260bd87fdf..1c1e9c10fb 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala @@ -189,7 +189,7 @@ abstract class TreeCheckers extends Analyzer { if (t.symbol == NoSymbol) errorFn(t.pos, "no symbol: " + treestr(t)) - override def typed(tree: Tree, mode: Int, pt: Type): Tree = returning(tree) { + override def typed(tree: Tree, mode: Mode, pt: Type): Tree = returning(tree) { case EmptyTree | TypeTree() => () case _ if tree.tpe != null => tpeOfTree.getOrElseUpdate(tree, try tree.tpe finally tree.clearType()) diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala index 56b43eaa41..ab1751b4f0 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala @@ -547,7 +547,7 @@ trait TypeDiagnostics { } // The checkDead call from typedArg is more selective. - def inMode(mode: Int, tree: Tree): Tree = { + def inMode(mode: Mode, tree: Tree): Tree = { val modeOK = (mode & (EXPRmode | BYVALmode | POLYmode)) == (EXPRmode | BYVALmode) if (modeOK) apply(tree) else tree diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index acbd71bc31..20907979e9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -16,6 +16,7 @@ import scala.collection.mutable import scala.reflect.internal.util.{ BatchSourceFile, Statistics, shortClassOfInstance } import mutable.ListBuffer import symtab.Flags._ +import Mode._ // Suggestion check whether we can do without priming scopes with symbols of outer scopes, // like the IDE does. @@ -24,7 +25,7 @@ import symtab.Flags._ * @author Martin Odersky * @version 1.0 */ -trait Typers extends Modes with Adaptations with Tags { +trait Typers extends Adaptations with Tags { self: Analyzer => import global._ @@ -32,7 +33,7 @@ trait Typers extends Modes with Adaptations with Tags { import TypersStats._ import patmat.DefaultOverrideMatchAttachment - final def forArgMode(fun: Tree, mode: Int) = + final def forArgMode(fun: Tree, mode: Mode) = if (treeInfo.isSelfOrSuperConstrCall(fun)) mode | SCCmode else mode @@ -525,11 +526,11 @@ trait Typers extends Modes with Adaptations with Tags { /** Does the context of tree `tree` require a stable type? */ - private def isStableContext(tree: Tree, mode: Int, pt: Type) = - isNarrowable(tree.tpe) && ((mode & (EXPRmode | LHSmode)) == EXPRmode) && + private def isStableContext(tree: Tree, mode: Mode, pt: Type) = + isNarrowable(tree.tpe) && mode.inExprMode && mode.inNone(LHSmode) && (xtypes || (pt.isStable || - (mode & QUALmode) != 0 && !tree.symbol.isConstant || + mode.inAll(QUALmode) && !tree.symbol.isConstant || pt.typeSymbol.isAbstractType && pt.bounds.lo.isStable && !(tree.tpe <:< pt)) || pt.typeSymbol.isRefinementClass && !(tree.tpe <:< pt)) @@ -583,15 +584,15 @@ trait Typers extends Modes with Adaptations with Tags { * 3. Turn tree type into stable type if possible and required by context. * 4. Give getClass calls a more precise type based on the type of the target of the call. */ - private def stabilize(tree: Tree, pre: Type, mode: Int, pt: Type): Tree = { - if (tree.symbol.isOverloaded && !inFunMode(mode)) + private def stabilize(tree: Tree, pre: Type, mode: Mode, pt: Type): Tree = { + if (tree.symbol.isOverloaded && !mode.inFunMode) inferExprAlternative(tree, pt) val sym = tree.symbol def fail() = NotAValueError(tree, sym) if (tree.isErrorTyped) tree - else if (inPatternNotFunMode(mode) && tree.isTerm) { // (1) + else if (mode.inPatternNotFunMode && tree.isTerm) { // (1) if (sym.isValue) { val tree1 = checkStable(tree) // A module reference in a pattern has type Foo.type, not "object Foo" @@ -625,7 +626,7 @@ trait Typers extends Modes with Adaptations with Tags { case _ => !phase.erasedTypes } - def stabilizeFun(tree: Tree, mode: Int, pt: Type): Tree = { + def stabilizeFun(tree: Tree, mode: Mode, pt: Type): Tree = { val sym = tree.symbol val pre = tree match { case Select(qual, _) => qual.tpe @@ -785,7 +786,7 @@ trait Typers extends Modes with Adaptations with Tags { * (14) When in mode EXPRmode, apply a view * If all this fails, error */ - protected def adapt(tree: Tree, mode: Int, pt: Type, original: Tree = EmptyTree): Tree = { + protected def adapt(tree: Tree, mode: Mode, pt: Type, original: Tree = EmptyTree): Tree = { def adaptToImplicitMethod(mt: MethodType): Tree = { if (context.undetparams.nonEmpty) { // (9) -- should revisit dropped condition `(mode & POLYmode) == 0` @@ -829,7 +830,7 @@ trait Typers extends Modes with Adaptations with Tags { case Block(_, tree1) => tree1.symbol case _ => tree.symbol } - if (!meth.isConstructor && !meth.isTermMacro && isFunctionType(pt)) { // (4.2) + if (!meth.isConstructor && isFunctionType(pt)) { // (4.2) debuglog("eta-expanding " + tree + ":" + tree.tpe + " to " + pt) checkParamsConvertible(tree, tree.tpe) val tree0 = etaExpand(context.unit, tree, this) @@ -854,13 +855,13 @@ trait Typers extends Modes with Adaptations with Tags { } def adaptType(): Tree = { - if (inFunMode(mode)) { + if (mode.inFunMode) { // todo. the commented line below makes sense for typechecking, say, TypeApply(Ident(`some abstract type symbol`), List(...)) // because otherwise Ident will have its tpe set to a TypeRef, not to a PolyType, and `typedTypeApply` will fail // but this needs additional investigation, because it crashes t5228, gadts1 and maybe something else // tree setType tree.tpe.normalize tree - } else if (tree.hasSymbolField && !tree.symbol.typeParams.isEmpty && !inHKMode(mode) && + } else if (tree.hasSymbolField && !tree.symbol.typeParams.isEmpty && !mode.inHKMode && !(tree.symbol.isJavaDefined && context.unit.isJava)) { // (7) // @M When not typing a higher-kinded type ((mode & HKmode) == 0) // or raw type (tree.symbol.isJavaDefined && context.unit.isJava), types must be of kind *, @@ -869,7 +870,7 @@ trait Typers extends Modes with Adaptations with Tags { MissingTypeParametersError(tree) } else if ( // (7.1) @M: check kind-arity // @M: removed check for tree.hasSymbolField and replace tree.symbol by tree.tpe.symbol (TypeTree's must also be checked here, and they don't directly have a symbol) - (inHKMode(mode)) && + mode.inHKMode && // @M: don't check tree.tpe.symbol.typeParams. check tree.tpe.typeParams!!! // (e.g., m[Int] --> tree.tpe.symbol.typeParams.length == 1, tree.tpe.typeParams.length == 0!) !sameLength(tree.tpe.typeParams, pt.typeParams) && @@ -992,7 +993,7 @@ trait Typers extends Modes with Adaptations with Tags { } def insertApply(): Tree = { - assert(!inHKMode(mode), modeString(mode)) //@M + assert(!mode.inHKMode, mode) //@M val adapted = adaptToName(tree, nme.apply) def stabilize0(pre: Type): Tree = stabilize(adapted, pre, EXPRmode | QUALmode, WildcardType) // TODO reconcile the overlap between Typers#stablize and TreeGen.stabilize @@ -1020,26 +1021,26 @@ trait Typers extends Modes with Adaptations with Tags { tree.tpe match { case atp @ AnnotatedType(_, _, _) if canAdaptAnnotations(tree, mode, pt) => // (-1) adaptAnnotations(tree, mode, pt) - case ct @ ConstantType(value) if inNoModes(mode, TYPEmode | FUNmode) && (ct <:< pt) && !forScaladoc && !forInteractive => // (0) + case ct @ ConstantType(value) if mode.inNone(TYPEmode | FUNmode) && (ct <:< pt) && !forScaladoc && !forInteractive => // (0) val sym = tree.symbol if (sym != null && sym.isDeprecated) { val msg = sym.toString + sym.locationString + " is deprecated: " + sym.deprecationMessage.getOrElse("") unit.deprecationWarning(tree.pos, msg) } treeCopy.Literal(tree, value) - case OverloadedType(pre, alts) if !inFunMode(mode) => // (1) + case OverloadedType(pre, alts) if !mode.inFunMode => // (1) inferExprAlternative(tree, pt) adapt(tree, mode, pt, original) case NullaryMethodType(restpe) => // (2) adapt(tree setType restpe, mode, pt, original) - case TypeRef(_, ByNameParamClass, List(arg)) if ((mode & EXPRmode) != 0) => // (2) + case TypeRef(_, ByNameParamClass, List(arg)) if mode.inExprMode => // (2) adapt(tree setType arg, mode, pt, original) case tr @ TypeRef(_, sym, _) if sym.isAliasType && tr.dealias.isInstanceOf[ExistentialType] && ((mode & (EXPRmode | LHSmode)) == EXPRmode) => adapt(tree setType tr.dealias.skolemizeExistential(context.owner, tree), mode, pt, original) case et @ ExistentialType(_, _) if ((mode & (EXPRmode | LHSmode)) == EXPRmode) => adapt(tree setType et.skolemizeExistential(context.owner, tree), mode, pt, original) - case PolyType(tparams, restpe) if inNoModes(mode, TAPPmode | PATTERNmode | HKmode) => // (3) + case PolyType(tparams, restpe) if mode.inNone(TAPPmode | PATTERNmode | HKmode) => // (3) // assert((mode & HKmode) == 0) //@M a PolyType in HKmode represents an anonymous type function, // we're in HKmode since a higher-kinded type is expected --> hence, don't implicitly apply it to type params! // ticket #2197 triggered turning the assert into a guard @@ -1058,18 +1059,19 @@ trait Typers extends Modes with Adaptations with Tags { adaptToImplicitMethod(mt) case mt: MethodType if (((mode & (EXPRmode | FUNmode | LHSmode)) == EXPRmode) && - (context.undetparams.isEmpty || inPolyMode(mode))) && !(tree.symbol != null && tree.symbol.isTermMacro) => + (context.undetparams.isEmpty || mode.inPolyMode)) && !treeInfo.isMacroApplicationOrBlock(tree) => instantiateToMethodType(mt) case _ => - def shouldInsertApply(tree: Tree) = inAllModes(mode, EXPRmode | FUNmode) && (tree.tpe match { + def vanillaAdapt(tree: Tree) = { + def shouldInsertApply(tree: Tree) = mode.inAll(EXPRmode | FUNmode) && (tree.tpe match { case _: MethodType | _: OverloadedType | _: PolyType => false case _ => applyPossible }) def applyPossible = { def applyMeth = member(adaptToName(tree, nme.apply), nme.apply) dyna.acceptsApplyDynamic(tree.tpe) || ( - if ((mode & TAPPmode) != 0) + if (mode.inAll(TAPPmode)) tree.tpe.typeParams.isEmpty && applyMeth.filter(!_.tpe.typeParams.isEmpty) != NoSymbol else applyMeth.filter(_.tpe.paramSectionCount > 0) != NoSymbol @@ -1077,18 +1079,13 @@ trait Typers extends Modes with Adaptations with Tags { } if (tree.isType) adaptType() - else if ( - inExprModeButNot(mode, FUNmode) && !tree.isDef && // typechecking application - tree.symbol != null && tree.symbol.isTermMacro && // of a macro - !tree.attachments.get[SuppressMacroExpansionAttachment.type].isDefined) - macroExpand(this, tree, mode, pt) - else if (inAllModes(mode, PATTERNmode | FUNmode)) + else if (mode.inAll(PATTERNmode | FUNmode)) adaptConstrPattern() else if (shouldInsertApply(tree)) insertApply() - else if (!context.undetparams.isEmpty && !inPolyMode(mode)) { // (9) - assert(!inHKMode(mode), modeString(mode)) //@M - if (inExprModeButNot(mode, FUNmode) && pt.typeSymbol == UnitClass) + else if (!context.undetparams.isEmpty && !mode.inPolyMode) { // (9) + assert(!mode.inHKMode, mode) //@M + if (mode.inExprModeButNot(FUNmode) && pt.typeSymbol == UnitClass) instantiateExpectingUnit(tree, mode) else instantiate(tree, mode, pt) @@ -1096,7 +1093,7 @@ trait Typers extends Modes with Adaptations with Tags { tree } else { def fallBack: Tree = { - if (inPatternMode(mode)) { + if (mode.inPatternMode) { if ((tree.symbol ne null) && tree.symbol.isModule) inferModulePattern(tree, pt) if (isPopulated(tree.tpe, approximateAbstracts(pt))) @@ -1105,7 +1102,7 @@ trait Typers extends Modes with Adaptations with Tags { val tree1 = constfold(tree, pt) // (10) (11) if (tree1.tpe <:< pt) adapt(tree1, mode, pt, original) else { - if (inExprModeButNot(mode, FUNmode)) { + if (mode.inExprModeButNot(FUNmode)) { pt.dealias match { case TypeRef(_, sym, _) => // note: was if (pt.typeSymbol == UnitClass) but this leads to a potentially @@ -1210,10 +1207,13 @@ trait Typers extends Modes with Adaptations with Tags { } fallBack } + } + val tree1 = if (mode.inExprModeButNot(FUNmode) && treeInfo.isMacroApplication(tree)) macroExpandApply(this, tree, mode, pt) else tree + if (tree == tree1) vanillaAdapt(tree1) else tree1 } } - def instantiate(tree: Tree, mode: Int, pt: Type): Tree = { + def instantiate(tree: Tree, mode: Mode, pt: Type): Tree = { inferExprInstance(tree, context.extractUndetparams(), pt) adapt(tree, mode, pt) } @@ -1221,7 +1221,7 @@ trait Typers extends Modes with Adaptations with Tags { * with expected type Unit, but if that fails, try again with pt = WildcardType * and discard the expression. */ - def instantiateExpectingUnit(tree: Tree, mode: Int): Tree = { + def instantiateExpectingUnit(tree: Tree, mode: Mode): Tree = { val savedUndetparams = context.undetparams silent(_.instantiate(tree, mode, UnitClass.tpe)) orElse { _ => context.undetparams = savedUndetparams @@ -1295,7 +1295,7 @@ trait Typers extends Modes with Adaptations with Tags { * a method `name`. If that's ambiguous try taking arguments into * account using `adaptToArguments`. */ - def adaptToMemberWithArgs(tree: Tree, qual: Tree, name: Name, mode: Int, reportAmbiguous: Boolean, saveErrors: Boolean): Tree = { + def adaptToMemberWithArgs(tree: Tree, qual: Tree, name: Name, mode: Mode, reportAmbiguous: Boolean, saveErrors: Boolean): Tree = { def onError(reportError: => Tree): Tree = context.tree match { case Apply(tree1, args) if (tree1 eq tree) && args.nonEmpty => ( silent (_.typedArgs(args, mode)) @@ -1588,7 +1588,11 @@ trait Typers extends Modes with Adaptations with Tags { else map2(preSuperStats, preSuperVals)((ldef, gdef) => gdef.tpt setType ldef.symbol.tpe) - if (superCall1 == cunit) EmptyTree else cbody2 + if (superCall1 == cunit) EmptyTree + else cbody2 match { + case Block(_, expr) => expr + case tree => tree + } case _ => EmptyTree } @@ -1631,7 +1635,7 @@ trait Typers extends Modes with Adaptations with Tags { ) } - def parentTypes(templ: Template): List[Tree] = templ.parents match { + def typedParentTypes(templ: Template): List[Tree] = templ.parents match { case Nil => List(atPos(templ.pos)(TypeTree(AnyRefClass.tpe))) case first :: rest => try { @@ -1653,7 +1657,7 @@ trait Typers extends Modes with Adaptations with Tags { case ex: TypeError => // fallback in case of cyclic errors // @H none of the tests enter here but I couldn't rule it out - // upd. @E when a definitions inherits itself, we end up here + // upd. @E when a definition inherits itself, we end up here // because `typedParentType` triggers `initialize` for parent types symbols log("Type error calculating parents in template " + templ) log("Error: " + ex) @@ -1764,7 +1768,7 @@ trait Typers extends Modes with Adaptations with Tags { reenterTypeParams(cdef.tparams) val tparams1 = cdef.tparams mapConserve (typedTypeDef) val impl1 = typerReportAnyContextErrors(context.make(cdef.impl, clazz, newScope)) { - _.typedTemplate(cdef.impl, parentTypes(cdef.impl)) + _.typedTemplate(cdef.impl, typedParentTypes(cdef.impl)) } val impl2 = finishMethodSynthesis(impl1, clazz, context) if (clazz.isTrait && clazz.info.parents.nonEmpty && clazz.info.firstParent.typeSymbol == AnyClass) @@ -1804,7 +1808,7 @@ trait Typers extends Modes with Adaptations with Tags { ) val impl1 = typerReportAnyContextErrors(context.make(mdef.impl, clazz, newScope)) { _.typedTemplate(mdef.impl, { - parentTypes(mdef.impl) ++ ( + typedParentTypes(mdef.impl) ++ ( if (noSerializable) Nil else { clazz.makeSerializable() @@ -2204,7 +2208,7 @@ trait Typers extends Modes with Adaptations with Tags { meth.owner.isAnonOrRefinementClass)) InvalidConstructorDefError(ddef) typed(ddef.rhs) - } else if (meth.isTermMacro) { + } else if (meth.isMacro) { // typechecking macro bodies is sort of unconventional // that's why we employ our custom typing scheme orchestrated outside of the typer transformedOr(ddef.rhs, typedMacroBody(this, ddef)) @@ -2318,7 +2322,7 @@ trait Typers extends Modes with Adaptations with Tags { } } - def typedBlock(block: Block, mode: Int, pt: Type): Block = { + def typedBlock(block: Block, mode: Mode, pt: Type): Block = { val syntheticPrivates = new ListBuffer[Symbol] try { namer.enterSyms(block.stats) @@ -2380,7 +2384,7 @@ trait Typers extends Modes with Adaptations with Tags { case _ => stat::Nil }) val stats2 = typedStats(stats1, context.owner) - val expr1 = typed(block.expr, mode & ~(FUNmode | QUALmode), pt) + val expr1 = typed(block.expr, mode &~ (FUNmode | QUALmode), pt) treeCopy.Block(block, stats2, expr1) .setType(if (treeInfo.isExprSafeToInline(block)) expr1.tpe else expr1.tpe.deconst) } finally { @@ -2429,21 +2433,7 @@ trait Typers extends Modes with Adaptations with Tags { } // body1 = checkNoEscaping.locals(context.scope, pt, body1) - val treeWithSkolems = treeCopy.CaseDef(cdef, pat1, guard1, body1) setType body1.tpe - - new TypeMapTreeSubstituter(deskolemizeGADTSkolems).traverse(treeWithSkolems) - - treeWithSkolems // now without skolems, actually - } - - // undo adaptConstrPattern's evil deeds, as they confuse the old pattern matcher - // the flags are used to avoid accidentally deskolemizing unrelated skolems of skolems - object deskolemizeGADTSkolems extends TypeMap { - def apply(tp: Type): Type = mapOver(tp) match { - case TypeRef(pre, sym, args) if sym.isGADTSkolem => - typeRef(NoPrefix, sym.deSkolemize, args) - case tp1 => tp1 - } + treeCopy.CaseDef(cdef, pat1, guard1, body1) setType body1.tpe } def typedCases(cases: List[CaseDef], pattp: Type, pt: Type): List[CaseDef] = @@ -2451,13 +2441,13 @@ trait Typers extends Modes with Adaptations with Tags { newTyper(context.makeNewScope(cdef, context.owner)).typedCase(cdef, pattp, pt) } - def adaptCase(cdef: CaseDef, mode: Int, tpe: Type): CaseDef = deriveCaseDef(cdef)(adapt(_, mode, tpe)) + def adaptCase(cdef: CaseDef, mode: Mode, tpe: Type): CaseDef = deriveCaseDef(cdef)(adapt(_, mode, tpe)) def ptOrLub(tps: List[Type], pt: Type ) = if (isFullyDefined(pt)) (pt, false) else weakLub(tps map (_.deconst)) def ptOrLubPacked(trees: List[Tree], pt: Type) = if (isFullyDefined(pt)) (pt, false) else weakLub(trees map (c => packedType(c, context.owner).deconst)) // takes untyped sub-trees of a match and type checks them - def typedMatch(selector: Tree, cases: List[CaseDef], mode: Int, pt: Type, tree: Tree = EmptyTree): Match = { + def typedMatch(selector: Tree, cases: List[CaseDef], mode: Mode, pt: Type, tree: Tree = EmptyTree): Match = { val selector1 = checkDead(typed(selector, EXPRmode | BYVALmode, WildcardType)) val selectorTp = packCaptured(selector1.tpe.widen).skolemizeExistential(context.owner, selector) val casesTyped = typedCases(cases, selectorTp, pt) @@ -2470,7 +2460,7 @@ trait Typers extends Modes with Adaptations with Tags { } // match has been typed -- virtualize it during type checking so the full context is available - def virtualizedMatch(match_ : Match, mode: Int, pt: Type) = { + def virtualizedMatch(match_ : Match, mode: Mode, pt: Type) = { import patmat.{ vpmName, PureMatchTranslator } // TODO: add fallback __match sentinel to predef @@ -2488,12 +2478,11 @@ trait Typers extends Modes with Adaptations with Tags { // Match(EmptyTree, cases) ==> new PartialFunction { def apply<OrElse>(params) = `translateMatch('`(param1,...,paramN)` match { cases }')` } // for fresh params, the selector of the match we'll translated simply gathers those in a tuple // NOTE: restricted to PartialFunction -- leave Function trees if the expected type does not demand a partial function - class MatchFunTyper(tree: Tree, cases: List[CaseDef], mode: Int, pt0: Type) { + class MatchFunTyper(tree: Tree, cases: List[CaseDef], mode: Mode, pt: Type) { // TODO: remove FunctionN support -- this is currently designed so that it can emit FunctionN and PartialFunction subclasses // however, we should leave Function nodes until Uncurry so phases after typer can still detect normal Function trees // we need to synthesize PartialFunction impls, though, to avoid nastiness in Uncurry in transforming&duplicating generated pattern matcher trees // TODO: remove PartialFunction support from UnCurry - private val pt = deskolemizeGADTSkolems(pt0) private val targs = pt.normalize.typeArgs private val arity = if (isFunctionType(pt)) targs.length - 1 else 1 // TODO pt should always be a (Partial)Function, right? private val ptRes = if (targs.isEmpty) WildcardType else targs.last // may not be fully defined @@ -2638,7 +2627,7 @@ trait Typers extends Modes with Adaptations with Tags { } // Function(params, Match(sel, cases)) ==> new <Partial>Function { def apply<OrElse>(params) = `translateMatch('sel match { cases }')` } - class MatchFunTyperBetaReduced(fun: Function, sel: Tree, cases: List[CaseDef], mode: Int, pt: Type) extends MatchFunTyper(fun, cases, mode, pt) { + class MatchFunTyperBetaReduced(fun: Function, sel: Tree, cases: List[CaseDef], mode: Mode, pt: Type) extends MatchFunTyper(fun, cases, mode, pt) { override def deriveFormals = fun.vparams map { p => if(p.tpt.tpe == null) typedType(p.tpt).tpe else p.tpt.tpe } @@ -2651,7 +2640,7 @@ trait Typers extends Modes with Adaptations with Tags { override def mkSel(params: List[Symbol]) = sel.duplicate } - private def typedFunction(fun: Function, mode: Int, pt: Type): Tree = { + private def typedFunction(fun: Function, mode: Mode, pt: Type): Tree = { val numVparams = fun.vparams.length if (numVparams > definitions.MaxFunctionArity) return MaxFunctionArityError(fun) @@ -2676,7 +2665,7 @@ trait Typers extends Modes with Adaptations with Tags { else { fun match { case etaExpansion(vparams, fn, args) => - silent(_.typed(fn, forFunMode(mode), pt)) filter (_ => context.undetparams.isEmpty) map { fn1 => + silent(_.typed(fn, mode.forFunMode, pt)) filter (_ => context.undetparams.isEmpty) map { fn1 => // if context,undetparams is not empty, the function was polymorphic, // so we need the missing arguments to infer its type. See #871 //println("typing eta "+fun+":"+fn1.tpe+"/"+context.undetparams) @@ -2881,14 +2870,14 @@ trait Typers extends Modes with Adaptations with Tags { } } - def typedArg(arg: Tree, mode: Int, newmode: Int, pt: Type): Tree = { - val typedMode = onlyStickyModes(mode) | newmode - val t = withCondConstrTyper((mode & SCCmode) != 0)(_.typed(arg, typedMode, pt)) + def typedArg(arg: Tree, mode: Mode, newmode: Mode, pt: Type): Tree = { + val typedMode = mode.onlySticky | newmode + val t = withCondConstrTyper((mode & SCCmode) != NOmode)(_.typed(arg, typedMode, pt)) checkDead.inMode(typedMode, t) } - def typedArgs(args: List[Tree], mode: Int) = - args mapConserve (arg => typedArg(arg, mode, 0, WildcardType)) + def typedArgs(args: List[Tree], mode: Mode) = + args mapConserve (arg => typedArg(arg, mode, NOmode, WildcardType)) /** Type trees in `args0` against corresponding expected type in `adapted0`. * @@ -2898,8 +2887,8 @@ trait Typers extends Modes with Adaptations with Tags { * * (docs reverse-engineered -- AM) */ - def typedArgs(args0: List[Tree], mode: Int, formals0: List[Type], adapted0: List[Type]): List[Tree] = { - val sticky = onlyStickyModes(mode) + def typedArgs(args0: List[Tree], mode: Mode, formals0: List[Type], adapted0: List[Type]): List[Tree] = { + val sticky = mode.onlySticky def loop(args: List[Tree], formals: List[Type], adapted: List[Type]): List[Tree] = { if (args.isEmpty || adapted.isEmpty) Nil else { @@ -2907,11 +2896,10 @@ trait Typers extends Modes with Adaptations with Tags { val isVarArgs = formals.isEmpty || formals.tail.isEmpty && isRepeatedParamType(formals.head) val typedMode = sticky | ( if (isVarArgs) STARmode | BYVALmode - else if (isByNameParamType(formals.head)) 0 + else if (isByNameParamType(formals.head)) NOmode else BYVALmode ) var tree = typedArg(args.head, mode, typedMode, adapted.head) - if (hasPendingMacroExpansions) tree = macroExpandAll(this, tree) // formals may be empty, so don't call tail tree :: loop(args.tail, formals drop 1, adapted.tail) } @@ -2959,7 +2947,7 @@ trait Typers extends Modes with Adaptations with Tags { } } - def doTypedApply(tree: Tree, fun0: Tree, args: List[Tree], mode: Int, pt: Type): Tree = { + def doTypedApply(tree: Tree, fun0: Tree, args: List[Tree], mode: Mode, pt: Type): Tree = { // TODO_NMT: check the assumption that args nonEmpty def duplErrTree = setError(treeCopy.Apply(tree, fun0, args)) def duplErrorTree(err: AbsTypeError) = { issue(err); duplErrTree } @@ -3001,7 +2989,7 @@ trait Typers extends Modes with Adaptations with Tags { if (sym1 != NoSymbol) sym = sym1 } if (sym == NoSymbol) fun - else adapt(fun setSymbol sym setType pre.memberType(sym), forFunMode(mode), WildcardType) + else adapt(fun setSymbol sym setType pre.memberType(sym), mode.forFunMode, WildcardType) } else fun } @@ -3034,7 +3022,7 @@ trait Typers extends Modes with Adaptations with Tags { setError(tree) else { inferMethodAlternative(fun, undetparams, argtpes.toList, pt) - doTypedApply(tree, adapt(fun, forFunMode(mode), WildcardType), args1, mode, pt) + doTypedApply(tree, adapt(fun, mode.forFunMode, WildcardType), args1, mode, pt) } } handleOverloaded @@ -3059,7 +3047,7 @@ trait Typers extends Modes with Adaptations with Tags { // Depending on user options, may warn or error here if // a Unit or tuple was inserted. Some(t) filter (tupledTree => - !inExprModeButNot(mode, FUNmode) + !mode.inExprModeButNot(FUNmode) || tupledTree.symbol == null || checkValidAdaptation(tupledTree, args) ) @@ -3077,12 +3065,12 @@ trait Typers extends Modes with Adaptations with Tags { val lencmp = compareLengths(args, formals) def checkNotMacro() = { - if (fun.symbol != null && fun.symbol.filter(sym => sym != null && sym.isTermMacro && !sym.isErroneous) != NoSymbol) + if (treeInfo.isMacroApplication(fun)) tryTupleApply getOrElse duplErrorTree(NamedAndDefaultArgumentsNotSupportedForMacros(tree, fun)) } if (mt.isErroneous) duplErrTree - else if (inPatternMode(mode)) { + else if (mode.inPatternMode) { // #2064 duplErrorTree(WrongNumberOfArgsError(tree, fun)) } else if (lencmp > 0) { @@ -3179,7 +3167,7 @@ trait Typers extends Modes with Adaptations with Tags { // precise(foo) : foo.type => foo.type val restpe = mt.resultType(args1 map (arg => gen.stableTypeFor(arg) getOrElse arg.tpe)) def ifPatternSkipFormals(tp: Type) = tp match { - case MethodType(_, rtp) if (inPatternMode(mode)) => rtp + case MethodType(_, rtp) if (mode.inPatternMode) => rtp case _ => tp } @@ -3203,7 +3191,7 @@ trait Typers extends Modes with Adaptations with Tags { doTypedApply(tree, fun, args, mode, pt) } else { def handlePolymorphicCall = { - assert(!inPatternMode(mode), modeString(mode)) // this case cannot arise for patterns + assert(!mode.inPatternMode, mode) // this case cannot arise for patterns val lenientTargs = protoTypeArgs(tparams, formals, mt.resultApprox, pt) val strictTargs = map2(lenientTargs, tparams)((targ, tparam) => if (targ == WildcardType) tparam.tpeHK else targ) @@ -3244,15 +3232,16 @@ trait Typers extends Modes with Adaptations with Tags { if (!tree.isErrorTyped) setError(tree) else tree // @H change to setError(treeCopy.Apply(tree, fun, args)) - case otpe if inPatternMode(mode) && unapplyMember(otpe).exists => + case otpe if mode.inPatternMode && unapplyMember(otpe).exists => doTypedUnapply(tree, fun0, fun, args, mode, pt) case _ => - duplErrorTree(ApplyWithoutArgsError(tree, fun)) + if (treeInfo.isMacroApplication(tree)) duplErrorTree(MacroTooManyArgumentListsError(tree, fun.symbol)) + else duplErrorTree(ApplyWithoutArgsError(tree, fun)) } } - def doTypedUnapply(tree: Tree, fun0: Tree, fun: Tree, args: List[Tree], mode: Int, pt: Type): Tree = { + def doTypedUnapply(tree: Tree, fun0: Tree, fun: Tree, args: List[Tree], mode: Mode, pt: Type): Tree = { def duplErrTree = setError(treeCopy.Apply(tree, fun0, args)) def duplErrorTree(err: AbsTypeError) = { issue(err); duplErrTree } @@ -3376,7 +3365,7 @@ trait Typers extends Modes with Adaptations with Tags { * * @param annClass the expected annotation class */ - def typedAnnotation(ann: Tree, mode: Int = EXPRmode, selfsym: Symbol = NoSymbol, annClass: Symbol = AnnotationClass, requireJava: Boolean = false): AnnotationInfo = { + def typedAnnotation(ann: Tree, mode: Mode = EXPRmode, selfsym: Symbol = NoSymbol, annClass: Symbol = AnnotationClass, requireJava: Boolean = false): AnnotationInfo = { var hasError: Boolean = false val pending = ListBuffer[AbsTypeError]() @@ -3421,7 +3410,7 @@ trait Typers extends Modes with Adaptations with Tags { // use of Array.apply[T: ClassTag](xs: T*): Array[T] // and Array.apply(x: Int, xs: Int*): Array[Int] (and similar) case Apply(fun, args) => - val typedFun = typed(fun, forFunMode(mode), WildcardType) + val typedFun = typed(fun, mode.forFunMode, WildcardType) if (typedFun.symbol.owner == ArrayModule.moduleClass && typedFun.symbol.name == nme.apply) pt match { case TypeRef(_, ArrayClass, targ :: _) => @@ -3465,7 +3454,7 @@ trait Typers extends Modes with Adaptations with Tags { val res = if (fun.isErroneous) ErroneousAnnotation else { - val typedFun @ Select(New(tpt), _) = typed(fun, forFunMode(mode), WildcardType) + val typedFun @ Select(New(tpt), _) = typed(fun, mode.forFunMode, WildcardType) val annType = tpt.tpe if (typedFun.isErroneous) ErroneousAnnotation @@ -3755,7 +3744,7 @@ trait Typers extends Modes with Adaptations with Tags { if (!checkClassType(tpt) && noGen) tpt else atPos(tree.pos)(gen.mkClassOf(tpt.tpe)) - protected def typedExistentialTypeTree(tree: ExistentialTypeTree, mode: Int): Tree = { + protected def typedExistentialTypeTree(tree: ExistentialTypeTree, mode: Mode): Tree = { for (wc <- tree.whereClauses) if (wc.symbol == NoSymbol) { namer.enterSym(wc); wc.symbol setFlag EXISTENTIAL } else context.scope enter wc.symbol @@ -3770,7 +3759,7 @@ trait Typers extends Modes with Adaptations with Tags { } // lifted out of typed1 because it's needed in typedImplicit0 - protected def typedTypeApply(tree: Tree, mode: Int, fun: Tree, args: List[Tree]): Tree = fun.tpe match { + protected def typedTypeApply(tree: Tree, mode: Mode, fun: Tree, args: List[Tree]): Tree = fun.tpe match { case OverloadedType(pre, alts) => inferPolyAlternatives(fun, args map (_.tpe)) val tparams = fun.symbol.typeParams //@M TODO: fun.symbol.info.typeParams ? (as in typedAppliedTypeTree) @@ -3859,7 +3848,7 @@ trait Typers extends Modes with Adaptations with Tags { // else false } - def typedNamedApply(orig: Tree, fun: Tree, args: List[Tree], mode: Int, pt: Type): Tree = { + def typedNamedApply(orig: Tree, fun: Tree, args: List[Tree], mode: Mode, pt: Type): Tree = { def argToBinding(arg: Tree): Tree = arg match { case AssignOrNamedArg(Ident(name), rhs) => gen.mkTuple(List(CODE.LIT(name.toString), rhs)) case _ => gen.mkTuple(List(CODE.LIT(""), arg)) @@ -3944,10 +3933,10 @@ trait Typers extends Modes with Adaptations with Tags { println(s) } - def typed1(tree: Tree, mode: Int, pt: Type): Tree = { - def isPatternMode = inPatternMode(mode) - def inPatternConstructor = inAllModes(mode, PATTERNmode | FUNmode) - def isQualifierMode = (mode & QUALmode) != 0 + def typed1(tree: Tree, mode: Mode, pt: Type): Tree = { + def isPatternMode = mode.inPatternMode + def inPatternConstructor = mode.inAll(PATTERNmode | FUNmode) + def isQualifierMode = mode.inAll(QUALmode) // Lookup in the given class using the root mirror. def lookupInOwner(owner: Symbol, name: Name): Symbol = @@ -3969,7 +3958,7 @@ trait Typers extends Modes with Adaptations with Tags { val ann = atd.annot val arg1 = typed(atd.arg, mode, pt) /** mode for typing the annotation itself */ - val annotMode = mode & ~TYPEmode | EXPRmode + val annotMode = (mode &~ TYPEmode) | EXPRmode def resultingTypeTree(tpe: Type) = { // we need symbol-ful originals for reification @@ -4071,7 +4060,7 @@ trait Typers extends Modes with Adaptations with Tags { else context.owner.newValue(name, tree.pos) if (name != nme.WILDCARD) { - if ((mode & ALTmode) != 0) VariableInPatternAlternativeError(tree) + if (mode.inAll(ALTmode)) VariableInPatternAlternativeError(tree) namer.enterInScope(sym) } @@ -4298,7 +4287,7 @@ trait Typers extends Modes with Adaptations with Tags { UnderscoreEtaError(expr1) } - def tryTypedArgs(args: List[Tree], mode: Int): Option[List[Tree]] = { + def tryTypedArgs(args: List[Tree], mode: Mode): Option[List[Tree]] = { val c = context.makeSilent(false) c.retyping = true try { @@ -4378,7 +4367,7 @@ trait Typers extends Modes with Adaptations with Tags { val stableApplication = (fun.symbol ne null) && fun.symbol.isMethod && fun.symbol.isStable if (stableApplication && isPatternMode) { // treat stable function applications f() as expressions. - typed1(tree, mode & ~PATTERNmode | EXPRmode, pt) + typed1(tree, (mode &~ PATTERNmode) | EXPRmode, pt) } else { val funpt = if (isPatternMode) pt else WildcardType val appStart = if (Statistics.canEnable) Statistics.startTimer(failedApplyNanos) else null @@ -4401,9 +4390,9 @@ trait Typers extends Modes with Adaptations with Tags { reportError } } - silent(_.typed(fun, forFunMode(mode), funpt), - if ((mode & EXPRmode) != 0) false else context.ambiguousErrors, - if ((mode & EXPRmode) != 0) tree else context.tree) match { + silent(_.typed(fun, mode.forFunMode, funpt), + if (mode.inExprMode) false else context.ambiguousErrors, + if (mode.inExprMode) tree else context.tree) match { case SilentResultValue(fun1) => val fun2 = if (stableApplication) stabilizeFun(fun1, mode, pt) else fun1 if (Statistics.canEnable) Statistics.incCounter(typedApplyCount) @@ -4543,7 +4532,7 @@ trait Typers extends Modes with Adaptations with Tags { val owntype = ( if (!mix.isEmpty) findMixinSuper(clazz.tpe) - else if ((mode & SUPERCONSTRmode) != 0) clazz.info.firstParent + else if (mode.inAll(SUPERCONSTRmode)) clazz.info.firstParent else intersectionType(clazz.info.parents) ) treeCopy.Super(tree, qual1, mix) setType SuperType(clazz.thisType, owntype) @@ -4587,7 +4576,7 @@ trait Typers extends Modes with Adaptations with Tags { // symbol not found? --> try to convert implicitly to a type that does have the required // member. Added `| PATTERNmode` to allow enrichment in patterns (so we can add e.g., an // xml member to StringContext, which in turn has an unapply[Seq] method) - if (name != nme.CONSTRUCTOR && inExprModeOr(mode, PATTERNmode)) { + if (name != nme.CONSTRUCTOR && mode.inExprModeOr(PATTERNmode)) { val qual1 = adaptToMemberWithArgs(tree, qual, name, mode, true, true) if ((qual1 ne qual) && !qual1.isErrorTyped) return typed(treeCopy.Select(tree, qual1, name), mode, pt) @@ -4760,7 +4749,7 @@ trait Typers extends Modes with Adaptations with Tags { setError(tree) } // ignore current variable scope in patterns to enforce linearity - val startContext = if (inNoModes(mode, PATTERNmode | TYPEPATmode)) context else context.outer + val startContext = if (mode.inNone(PATTERNmode | TYPEPATmode)) context else context.outer val nameLookup = tree.symbol match { case NoSymbol => startContext.lookupSymbol(name, qualifies) case sym => LookupSucceeded(EmptyTree, sym) @@ -4796,8 +4785,8 @@ trait Typers extends Modes with Adaptations with Tags { def typedIdentOrWildcard(tree: Ident) = { val name = tree.name if (Statistics.canEnable) Statistics.incCounter(typedIdentCount) - if ((name == nme.WILDCARD && (mode & (PATTERNmode | FUNmode)) == PATTERNmode) || - (name == tpnme.WILDCARD && (mode & TYPEmode) != 0)) + if ((name == nme.WILDCARD && mode.inPatternNotFunMode) || + (name == tpnme.WILDCARD && mode.inAll(TYPEmode))) tree setType makeFullyDefined(pt) else typedIdent(tree, name) @@ -4920,7 +4909,7 @@ trait Typers extends Modes with Adaptations with Tags { } def typedStar(tree: Star) = { - if ((mode & STARmode) == 0 && !isPastTyper) + if (mode.inNone(STARmode) && !isPastTyper) StarPatternWithVarargParametersError(tree) treeCopy.Star(tree, typed(tree.elem, mode, pt)) setType makeFullyDefined(pt) } @@ -4971,16 +4960,16 @@ trait Typers extends Modes with Adaptations with Tags { // that typecheck must not trigger macro expansions, so we explicitly prohibit them // however we cannot do `context.withMacrosDisabled` // because `expr` might contain nested macro calls (see SI-6673) - val exprTyped = typed1(expr updateAttachment SuppressMacroExpansionAttachment, mode, pt) + val exprTyped = typed1(suppressMacroExpansion(expr), mode, pt) exprTyped match { - case macroDef if macroDef.symbol != null && macroDef.symbol.isTermMacro && !macroDef.symbol.isErroneous => + case macroDef if treeInfo.isMacroApplication(macroDef) => MacroEtaError(exprTyped) case _ => typedEta(checkDead(exprTyped)) } case Ident(tpnme.WILDCARD_STAR) => - val exprTyped = typed(expr, onlyStickyModes(mode), WildcardType) + val exprTyped = typed(expr, mode.onlySticky, WildcardType) def subArrayType(pt: Type) = if (isPrimitiveValueClass(pt.typeSymbol) || !isFullyDefined(pt)) arrayType(pt) else { @@ -4989,8 +4978,8 @@ trait Typers extends Modes with Adaptations with Tags { } val (exprAdapted, baseClass) = exprTyped.tpe.typeSymbol match { - case ArrayClass => (adapt(exprTyped, onlyStickyModes(mode), subArrayType(pt)), ArrayClass) - case _ => (adapt(exprTyped, onlyStickyModes(mode), seqType(pt)), SeqClass) + case ArrayClass => (adapt(exprTyped, mode.onlySticky, subArrayType(pt)), ArrayClass) + case _ => (adapt(exprTyped, mode.onlySticky, seqType(pt)), SeqClass) } exprAdapted.tpe.baseType(baseClass) match { case TypeRef(_, _, List(elemtp)) => @@ -5001,7 +4990,7 @@ trait Typers extends Modes with Adaptations with Tags { case _ => val tptTyped = typedType(tpt, mode) - val exprTyped = typed(expr, onlyStickyModes(mode), tptTyped.tpe.deconst) + val exprTyped = typed(expr, mode.onlySticky, tptTyped.tpe.deconst) val treeTyped = treeCopy.Typed(tree, exprTyped, tptTyped) if (isPatternMode) { @@ -5033,7 +5022,7 @@ trait Typers extends Modes with Adaptations with Tags { //val undets = context.undetparams // @M: fun is typed in TAPPmode because it is being applied to its actual type parameters - val fun1 = typed(fun, forFunMode(mode) | TAPPmode, WildcardType) + val fun1 = typed(fun, mode.forFunMode | TAPPmode, WildcardType) val tparams = fun1.symbol.typeParams //@M TODO: val undets_fun = context.undetparams ? @@ -5186,7 +5175,7 @@ trait Typers extends Modes with Adaptations with Tags { } } - def typed(tree: Tree, mode: Int, pt: Type): Tree = { + def typed(tree: Tree, mode: Mode, pt: Type): Tree = { lastTreeToTyper = tree indentTyping() @@ -5206,7 +5195,7 @@ trait Typers extends Modes with Adaptations with Tags { "undetparams" -> context.undetparams, "implicitsEnabled" -> context.implicitsEnabled, "enrichmentEnabled" -> context.enrichmentEnabled, - "mode" -> modeString(mode), + "mode" -> mode, "silent" -> context.bufferErrors, "context.owner" -> context.owner ) @@ -5226,7 +5215,12 @@ trait Typers extends Modes with Adaptations with Tags { } tree1 modifyType (addAnnotations(tree1, _)) - val result = if (tree1.isEmpty) tree1 else adapt(tree1, mode, pt, tree) + val result = + if (tree1.isEmpty) tree1 + else { + val result = adapt(tree1, mode, pt, tree) + if (hasPendingMacroExpansions) macroExpandAll(this, result) else result + } if (!alreadyTyped) { printTyping("adapted %s: %s to %s, %s".format( @@ -5269,7 +5263,7 @@ trait Typers extends Modes with Adaptations with Tags { ret } - def typedPos(pos: Position, mode: Int, pt: Type)(tree: Tree) = typed(atPos(pos)(tree), mode, pt) + def typedPos(pos: Position, mode: Mode, pt: Type)(tree: Tree) = typed(atPos(pos)(tree), mode, pt) def typedPos(pos: Position)(tree: Tree) = typed(atPos(pos)(tree)) // TODO: see if this formulation would impose any penalty, since // it makes for a lot less casting. @@ -5283,13 +5277,13 @@ trait Typers extends Modes with Adaptations with Tags { /** Types qualifier `tree` of a select node. * E.g. is tree occurs in a context like `tree.m`. */ - def typedQualifier(tree: Tree, mode: Int, pt: Type): Tree = + def typedQualifier(tree: Tree, mode: Mode, pt: Type): Tree = typed(tree, EXPRmode | QUALmode | POLYmode | mode & TYPEPATmode, pt) // TR: don't set BYVALmode, since qualifier might end up as by-name param to an implicit /** Types qualifier `tree` of a select node. * E.g. is tree occurs in a context like `tree.m`. */ - def typedQualifier(tree: Tree, mode: Int): Tree = + def typedQualifier(tree: Tree, mode: Mode): Tree = typedQualifier(tree, mode, WildcardType) def typedQualifier(tree: Tree): Tree = typedQualifier(tree, NOmode, WildcardType) @@ -5322,23 +5316,23 @@ trait Typers extends Modes with Adaptations with Tags { } /** Types a (fully parameterized) type tree */ - def typedType(tree: Tree, mode: Int): Tree = - typed(tree, forTypeMode(mode), WildcardType) + def typedType(tree: Tree, mode: Mode): Tree = + typed(tree, mode.forTypeMode, WildcardType) /** Types a (fully parameterized) type tree */ def typedType(tree: Tree): Tree = typedType(tree, NOmode) /** Types a higher-kinded type tree -- pt denotes the expected kind*/ - def typedHigherKindedType(tree: Tree, mode: Int, pt: Type): Tree = + def typedHigherKindedType(tree: Tree, mode: Mode, pt: Type): Tree = if (pt.typeParams.isEmpty) typedType(tree, mode) // kind is known and it's * else typed(tree, HKmode, pt) - def typedHigherKindedType(tree: Tree, mode: Int): Tree = + def typedHigherKindedType(tree: Tree, mode: Mode): Tree = typed(tree, HKmode, WildcardType) /** Types a type constructor tree used in a new or supertype */ - def typedTypeConstructor(tree: Tree, mode: Int): Tree = { - val result = typed(tree, forTypeMode(mode) | FUNmode, WildcardType) + def typedTypeConstructor(tree: Tree, mode: Mode): Tree = { + val result = typed(tree, mode.forTypeMode | FUNmode, WildcardType) // get rid of type aliases for the following check (#1241) result.tpe.dealias match { @@ -5359,7 +5353,7 @@ trait Typers extends Modes with Adaptations with Tags { def computeType(tree: Tree, pt: Type): Type = { // macros employ different logic of `computeType` - assert(!context.owner.isTermMacro, context.owner) + assert(!context.owner.isMacro, context.owner) val tree1 = typed(tree, pt) transformed(tree) = tree1 val tpe = packedType(tree1, context.owner) @@ -5368,8 +5362,8 @@ trait Typers extends Modes with Adaptations with Tags { } def computeMacroDefType(tree: Tree, pt: Type): Type = { - assert(context.owner.isTermMacro, context.owner) - assert(tree.symbol.isTermMacro, tree.symbol) + assert(context.owner.isMacro, context.owner) + assert(tree.symbol.isMacro, tree.symbol) assert(tree.isInstanceOf[DefDef], tree.getClass) val ddef = tree.asInstanceOf[DefDef] @@ -5395,7 +5389,7 @@ trait Typers extends Modes with Adaptations with Tags { case None => op } - def transformedOrTyped(tree: Tree, mode: Int, pt: Type): Tree = transformed.get(tree) match { + def transformedOrTyped(tree: Tree, mode: Mode, pt: Type): Tree = transformed.get(tree) match { case Some(tree1) => transformed -= tree; tree1 case None => typed(tree, mode, pt) } diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala index 834f5436dc..7b065e7cf6 100644 --- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala +++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala @@ -1,6 +1,7 @@ package scala.tools package reflect +import scala.tools.nsc.EXPRmode import scala.tools.nsc.reporters._ import scala.tools.nsc.CompilerCommand import scala.tools.nsc.io.VirtualDirectory @@ -163,7 +164,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => transformDuringTyper(expr, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled)( (currentTyper, expr) => { trace("typing (implicit views = %s, macros = %s): ".format(!withImplicitViewsDisabled, !withMacrosDisabled))(showAttributed(expr, true, true, settings.Yshowsymkinds.value)) - currentTyper.silent(_.typed(expr, analyzer.EXPRmode, pt)) match { + currentTyper.silent(_.typed(expr, EXPRmode, pt)) match { case analyzer.SilentResultValue(result) => trace("success: ")(showAttributed(result, true, true, settings.Yshowsymkinds.value)) result diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala index cf5b1fa2c4..600b51f376 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala @@ -2,11 +2,10 @@ package scala.tools.selectivecps -import scala.tools.nsc.Global -import scala.tools.nsc.typechecker.Modes +import scala.tools.nsc.{ Global, Mode } import scala.tools.nsc.MissingRequirementError -abstract class CPSAnnotationChecker extends CPSUtils with Modes { +abstract class CPSAnnotationChecker extends CPSUtils { val global: Global import global._ import definitions._ @@ -117,14 +116,14 @@ abstract class CPSAnnotationChecker extends CPSUtils with Modes { bounds } - override def canAdaptAnnotations(tree: Tree, mode: Int, pt: Type): Boolean = { + override def canAdaptAnnotations(tree: Tree, mode: Mode, pt: Type): Boolean = { if (!cpsEnabled) return false - vprintln("can adapt annotations? " + tree + " / " + tree.tpe + " / " + Integer.toHexString(mode) + " / " + pt) + vprintln("can adapt annotations? " + tree + " / " + tree.tpe + " / " + mode + " / " + pt) val annots1 = cpsParamAnnotation(tree.tpe) val annots2 = cpsParamAnnotation(pt) - if ((mode & global.analyzer.PATTERNmode) != 0) { + if (mode.inPatternMode) { //println("can adapt pattern annotations? " + tree + " / " + tree.tpe + " / " + Integer.toHexString(mode) + " / " + pt) if (!annots1.isEmpty) { return true @@ -133,7 +132,7 @@ abstract class CPSAnnotationChecker extends CPSUtils with Modes { /* // not precise enough -- still relying on addAnnotations to remove things from ValDef symbols - if ((mode & global.analyzer.TYPEmode) != 0 && (mode & global.analyzer.BYVALmode) != 0) { + if ((mode & TYPEmode) != 0 && (mode & BYVALmode) != 0) { if (!annots1.isEmpty) { return true } @@ -142,16 +141,16 @@ abstract class CPSAnnotationChecker extends CPSUtils with Modes { /* this interferes with overloading resolution - if ((mode & global.analyzer.BYVALmode) != 0 && tree.tpe <:< pt) { + if ((mode & BYVALmode) != 0 && tree.tpe <:< pt) { vprintln("already compatible, can't adapt further") return false } */ - if ((mode & global.analyzer.EXPRmode) != 0) { + if (mode.inExprMode) { if ((annots1 corresponds annots2)(_.atp <:< _.atp)) { vprintln("already same, can't adapt further") false - } else if (annots1.isEmpty && !annots2.isEmpty && ((mode & global.analyzer.BYVALmode) == 0)) { + } else if (annots1.isEmpty && !annots2.isEmpty && !mode.inByValMode) { //println("can adapt annotations? " + tree + " / " + tree.tpe + " / " + Integer.toHexString(mode) + " / " + pt) if (!hasPlusMarker(tree.tpe)) { // val base = tree.tpe <:< removeAllCPSAnnotations(pt) @@ -164,10 +163,10 @@ abstract class CPSAnnotationChecker extends CPSUtils with Modes { true //} } else false - } else if (!hasPlusMarker(tree.tpe) && annots1.isEmpty && !annots2.isEmpty && ((mode & global.analyzer.RETmode) != 0)) { + } else if (!hasPlusMarker(tree.tpe) && annots1.isEmpty && !annots2.isEmpty && mode.inRetMode) { vprintln("checking enclosing method's result type without annotations") tree.tpe <:< pt.withoutAnnotations - } else if (!hasMinusMarker(tree.tpe) && !annots1.isEmpty && ((mode & global.analyzer.BYVALmode) != 0)) { + } else if (!hasMinusMarker(tree.tpe) && !annots1.isEmpty && mode.inByValMode) { val optCpsTypes: Option[(Type, Type)] = cpsParamTypes(tree.tpe) val optExpectedCpsTypes: Option[(Type, Type)] = cpsParamTypes(pt) if (optCpsTypes.isEmpty || optExpectedCpsTypes.isEmpty) { @@ -183,21 +182,21 @@ abstract class CPSAnnotationChecker extends CPSUtils with Modes { } else false } - override def adaptAnnotations(tree: Tree, mode: Int, pt: Type): Tree = { + override def adaptAnnotations(tree: Tree, mode: Mode, pt: Type): Tree = { if (!cpsEnabled) return tree - vprintln("adapt annotations " + tree + " / " + tree.tpe + " / " + modeString(mode) + " / " + pt) + vprintln("adapt annotations " + tree + " / " + tree.tpe + " / " + mode + " / " + pt) - val patMode = (mode & global.analyzer.PATTERNmode) != 0 - val exprMode = (mode & global.analyzer.EXPRmode) != 0 - val byValMode = (mode & global.analyzer.BYVALmode) != 0 - val retMode = (mode & global.analyzer.RETmode) != 0 + val patMode = mode.inPatternMode + val exprMode = mode.inExprMode + val byValMode = mode.inByValMode + val retMode = mode.inRetMode val annotsTree = cpsParamAnnotation(tree.tpe) val annotsExpected = cpsParamAnnotation(pt) // not sure I rephrased this comment correctly: - // replacing `patMode` in the condition below by `patMode || ((mode & global.analyzer.TYPEmode) != 0 && (mode & global.analyzer.BYVALmode))` + // replacing `patMode` in the condition below by `patMode || ((mode & TYPEmode) != 0 && (mode & BYVALmode))` // doesn't work correctly -- still relying on addAnnotations to remove things from ValDef symbols if (patMode && !annotsTree.isEmpty) tree modifyType removeAllCPSAnnotations else if (exprMode && !byValMode && !hasPlusMarker(tree.tpe) && annotsTree.isEmpty && annotsExpected.nonEmpty) { // shiftUnit diff --git a/src/jline/src/main/java/scala/tools/jline/console/ConsoleReader.java b/src/jline/src/main/java/scala/tools/jline/console/ConsoleReader.java index 9df42708bb..a375b84a5c 100644 --- a/src/jline/src/main/java/scala/tools/jline/console/ConsoleReader.java +++ b/src/jline/src/main/java/scala/tools/jline/console/ConsoleReader.java @@ -1712,7 +1712,7 @@ public class ConsoleReader } /** - * Output a platform-dependant newline. + * Output a platform-dependent newline. */ public final void println() throws IOException { print(CR); diff --git a/src/partest/README b/src/partest/README index 0434aa7499..17594dbb1e 100644 --- a/src/partest/README +++ b/src/partest/README @@ -24,7 +24,6 @@ Other arguments: * --run next files test the interpreter and all backends * --jvm next files test the JVM backend * --res next files test the resident compiler - * --buildmanager next files test the build manager * --shootout next files are shootout tests * --script next files test the script runner * ''-Dpartest.scalac_opts=...'' -> add compiler options diff --git a/src/partest/scala/tools/partest/PartestTask.scala b/src/partest/scala/tools/partest/PartestTask.scala index 41d69a5448..d320f20616 100644 --- a/src/partest/scala/tools/partest/PartestTask.scala +++ b/src/partest/scala/tools/partest/PartestTask.scala @@ -43,7 +43,6 @@ import org.apache.tools.ant.types.Commandline.Argument * - `runtests`, * - `jvmtests`, * - `residenttests`, - * - `buildmanagertests`, * - `shootouttests`, * - `scalaptests`, * - `scalachecktests`, @@ -76,10 +75,6 @@ class PartestTask extends Task with CompilationPathProperty { residentFiles = Some(input) } - def addConfiguredBuildManagerTests(input: FileSet) { - buildManagerFiles = Some(input) - } - def addConfiguredScalacheckTests(input: FileSet) { scalacheckFiles = Some(input) } @@ -187,7 +182,6 @@ class PartestTask extends Task with CompilationPathProperty { private var runFiles: Option[FileSet] = None private var jvmFiles: Option[FileSet] = None private var residentFiles: Option[FileSet] = None - private var buildManagerFiles: Option[FileSet] = None private var scalacheckFiles: Option[FileSet] = None private var scriptFiles: Option[FileSet] = None private var shootoutFiles: Option[FileSet] = None @@ -244,7 +238,6 @@ class PartestTask extends Task with CompilationPathProperty { private def getRunFiles = getFilesAndDirs(runFiles) private def getJvmFiles = getFilesAndDirs(jvmFiles) private def getResidentFiles = getFiles(residentFiles) - private def getBuildManagerFiles = getFilesAndDirs(buildManagerFiles) private def getScalacheckFiles = getFilesAndDirs(scalacheckFiles) private def getScriptFiles = getFiles(scriptFiles) private def getShootoutFiles = getFiles(shootoutFiles) @@ -363,7 +356,6 @@ class PartestTask extends Task with CompilationPathProperty { (getRunFiles, "run", "Compiling and running files"), (getJvmFiles, "jvm", "Compiling and running files"), (getResidentFiles, "res", "Running resident compiler scenarii"), - (getBuildManagerFiles, "buildmanager", "Running Build Manager scenarii"), (getScalacheckFiles, "scalacheck", "Running scalacheck tests"), (getScriptFiles, "script", "Running script files"), (getShootoutFiles, "shootout", "Running shootout tests"), diff --git a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala index d146618d0e..6a24926b14 100644 --- a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala +++ b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala @@ -31,7 +31,6 @@ class ConsoleRunner extends DirectRunner { TestSet("run", stdFilter, "Testing interpreter and backend"), TestSet("jvm", stdFilter, "Testing JVM backend"), TestSet("res", x => x.isFile && (x hasExtension "res"), "Testing resident compiler"), - TestSet("buildmanager", _.isDirectory, "Testing Build Manager"), TestSet("shootout", stdFilter, "Testing shootout tests"), TestSet("script", stdFilter, "Testing script tests"), TestSet("scalacheck", stdFilter, "Testing ScalaCheck tests"), diff --git a/src/partest/scala/tools/partest/nest/NestUI.scala b/src/partest/scala/tools/partest/nest/NestUI.scala index ab90d387d0..df90b22448 100644 --- a/src/partest/scala/tools/partest/nest/NestUI.scala +++ b/src/partest/scala/tools/partest/nest/NestUI.scala @@ -73,7 +73,6 @@ object NestUI { println(" --run run interpreter and backend tests") println(" --jvm run JVM backend tests") println(" --res run resident compiler tests") - println(" --buildmanager run Build Manager tests") println(" --scalacheck run ScalaCheck tests") println(" --script run script runner tests") println(" --shootout run shootout tests") diff --git a/src/partest/scala/tools/partest/nest/RunnerManager.scala b/src/partest/scala/tools/partest/nest/RunnerManager.scala index fbef97dab4..0ed14dc858 100644 --- a/src/partest/scala/tools/partest/nest/RunnerManager.scala +++ b/src/partest/scala/tools/partest/nest/RunnerManager.scala @@ -19,7 +19,6 @@ import scala.tools.nsc.util.{ ClassPath, FakePos, ScalaClassLoader, stackTraceSt import ClassPath.{ join, split } import scala.tools.scalap.scalax.rules.scalasig.ByteCode import scala.collection.{ mutable, immutable } -import scala.tools.nsc.interactive.{ BuildManager, RefinedBuildManager } import scala.sys.process._ import java.util.concurrent.{ Executors, TimeUnit, TimeoutException } import PartestDefaults.{ javaCmd, javacCmd } @@ -530,121 +529,6 @@ class RunnerManager(kind: String, val fileManager: FileManager, params: TestRunP case "ant" => runAntTest(file) - case "buildmanager" => - val (swr, wr) = newTestWriters() - printInfoStart(file, wr) - val (outDir, testFile, changesDir) = { - if (!file.isDirectory) - (null, null, null) - else { - NestUI.verbose(this+" running test "+fileBase) - val outDir = createOutputDir() - val testFile = new File(file, fileBase + ".test") - val changesDir = new File(file, fileBase + ".changes") - - if (changesDir.isFile || !testFile.isFile) { - // if changes exists then it has to be a dir - if (!testFile.isFile) NestUI.verbose("invalid build manager test file") - if (changesDir.isFile) NestUI.verbose("invalid build manager changes directory") - (null, null, null) - } - else { - copyTestFiles(file, outDir) - NestUI.verbose("outDir: "+outDir) - NestUI.verbose("logFile: "+logFile) - (outDir, testFile, changesDir) - } - } - } - if (outDir == null) - return (false, LogContext(logFile)) - - // Pre-conditions satisfied - val sourcepath = outDir.getAbsolutePath+File.separator - - // configure input/output files - val logWriter = new PrintStream(new FileOutputStream(logFile), true) - val testReader = new BufferedReader(new FileReader(testFile)) - val logConsoleWriter = new PrintWriter(logWriter, true) - - // create proper settings for the compiler - val settings = new Settings(workerError) - settings.outdir.value = outDir.getAbsoluteFile.getAbsolutePath - settings.sourcepath.value = sourcepath - settings.classpath.value = fileManager.CLASSPATH - settings.Ybuildmanagerdebug.value = true - - // simulate Build Manager loop - val prompt = "builder > " - val reporter = new ConsoleReporter(settings, scala.Console.in, logConsoleWriter) - val bM: BuildManager = - new RefinedBuildManager(settings) { - override protected def newCompiler(settings: Settings) = - new BuilderGlobal(settings, reporter) - } - - def testCompile(line: String): Boolean = { - NestUI.verbose("compiling " + line) - val args = (line split ' ').toList - val command = new CompilerCommand(args, settings) - command.ok && { - bM.update(filesToSet(settings.sourcepath.value, command.files), Set.empty) - !reporter.hasErrors - } - } - - val updateFiles = (line: String) => { - NestUI.verbose("updating " + line) - (line split ' ').toList forall (u => - (u split "=>").toList match { - case origFileName::(newFileName::Nil) => - val newFile = new File(changesDir, newFileName) - if (newFile.isFile) { - val v = overwriteFileWith(new File(outDir, origFileName), newFile) - if (!v) - NestUI.verbose("'update' operation on " + u + " failed") - v - } else { - NestUI.verbose("File " + newFile + " is invalid") - false - } - case a => - NestUI.verbose("Other =: " + a) - false - } - ) - } - - def loop(): Boolean = { - testReader.readLine() match { - case null | "" => - NestUI.verbose("finished") - true - case s if s startsWith ">>update " => - updateFiles(s stripPrefix ">>update ") && loop() - case s if s startsWith ">>compile " => - val files = s stripPrefix ">>compile " - logWriter.println(prompt + files) - // In the end, it can finish with an error - if (testCompile(files)) loop() - else { - val t = testReader.readLine() - (t == null) || (t == "") - } - case s => - NestUI.verbose("wrong command in test file: " + s) - false - } - } - - Output.withRedirected(logWriter) { - try loop() - finally testReader.close() - } - fileManager.mapFile(logFile, replaceSlashes(new File(sourcepath), _)) - - (diffCheck(file, compareOutput(file, logFile)), LogContext(logFile, swr, wr)) - case "res" => { // simulate resident compiler loop val prompt = "\nnsc> " diff --git a/src/partest/scala/tools/partest/nest/TestFile.scala b/src/partest/scala/tools/partest/nest/TestFile.scala index 87177772ab..880c6e431b 100644 --- a/src/partest/scala/tools/partest/nest/TestFile.scala +++ b/src/partest/scala/tools/partest/nest/TestFile.scala @@ -54,7 +54,6 @@ abstract class TestFile(val kind: String) extends TestFileCommon { case class PosTestFile(file: JFile, fileManager: FileManager) extends TestFile("pos") case class NegTestFile(file: JFile, fileManager: FileManager) extends TestFile("neg") case class RunTestFile(file: JFile, fileManager: FileManager) extends TestFile("run") -case class BuildManagerTestFile(file: JFile, fileManager: FileManager) extends TestFile("bm") case class ScalaCheckTestFile(file: JFile, fileManager: FileManager) extends TestFile("scalacheck") case class JvmTestFile(file: JFile, fileManager: FileManager) extends TestFile("jvm") case class ShootoutTestFile(file: JFile, fileManager: FileManager) extends TestFile("shootout") { diff --git a/src/reflect/scala/reflect/internal/AnnotationCheckers.scala b/src/reflect/scala/reflect/internal/AnnotationCheckers.scala index 5318d3e540..13346d9151 100644 --- a/src/reflect/scala/reflect/internal/AnnotationCheckers.scala +++ b/src/reflect/scala/reflect/internal/AnnotationCheckers.scala @@ -39,14 +39,14 @@ trait AnnotationCheckers { /** Decide whether this annotation checker can adapt a tree * that has an annotated type to the given type tp, taking * into account the given mode (see method adapt in trait Typers).*/ - def canAdaptAnnotations(tree: Tree, mode: Int, pt: Type): Boolean = false + def canAdaptAnnotations(tree: Tree, mode: Mode, pt: Type): Boolean = false /** Adapt a tree that has an annotated type to the given type tp, * taking into account the given mode (see method adapt in trait Typers). * An implementation cannot rely on canAdaptAnnotations being called * before. If the implementing class cannot do the adaptiong, it * should return the tree unchanged.*/ - def adaptAnnotations(tree: Tree, mode: Int, pt: Type): Tree = tree + def adaptAnnotations(tree: Tree, mode: Mode, pt: Type): Tree = tree /** Adapt the type of a return expression. The decision of an annotation checker * whether the type should be adapted is based on the type of the expression @@ -113,7 +113,7 @@ trait AnnotationCheckers { /** Find out whether any annotation checker can adapt a tree * to a given type. Called by Typers.adapt. */ - def canAdaptAnnotations(tree: Tree, mode: Int, pt: Type): Boolean = { + def canAdaptAnnotations(tree: Tree, mode: Mode, pt: Type): Boolean = { annotationCheckers.exists(_.canAdaptAnnotations(tree, mode, pt)) } @@ -121,7 +121,7 @@ trait AnnotationCheckers { * to a given type (called by Typers.adapt). Annotation checkers * that cannot do the adaption should pass the tree through * unchanged. */ - def adaptAnnotations(tree: Tree, mode: Int, pt: Type): Tree = { + def adaptAnnotations(tree: Tree, mode: Mode, pt: Type): Tree = { annotationCheckers.foldLeft(tree)((tree, checker) => checker.adaptAnnotations(tree, mode, pt)) } @@ -129,7 +129,7 @@ trait AnnotationCheckers { /** Let a registered annotation checker adapt the type of a return expression. * Annotation checkers that cannot do the adaptation should simply return * the `default` argument. - * + * * Note that the result is undefined if more than one annotation checker * returns an adapted type which is not a subtype of `default`. */ diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index d165f66004..edd295aa65 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -401,7 +401,6 @@ trait Definitions extends api.StandardDefinitions { lazy val RemoteExceptionClass = requiredClass[java.rmi.RemoteException] lazy val ByNameParamClass = specialPolyClass(tpnme.BYNAME_PARAM_CLASS_NAME, COVARIANT)(_ => AnyClass.tpe) - lazy val EqualsPatternClass = specialPolyClass(tpnme.EQUALS_PATTERN_NAME, 0L)(_ => AnyClass.tpe) lazy val JavaRepeatedParamClass = specialPolyClass(tpnme.JAVA_REPEATED_PARAM_CLASS_NAME, COVARIANT)(tparam => arrayType(tparam.tpe)) lazy val RepeatedParamClass = specialPolyClass(tpnme.REPEATED_PARAM_CLASS_NAME, COVARIANT)(tparam => seqType(tparam.tpe)) @@ -902,6 +901,7 @@ trait Definitions extends api.StandardDefinitions { lazy val GetterTargetClass = requiredClass[meta.getter] lazy val ParamTargetClass = requiredClass[meta.param] lazy val SetterTargetClass = requiredClass[meta.setter] + lazy val ObjectTargetClass = requiredClass[meta.companionObject] lazy val ClassTargetClass = requiredClass[meta.companionClass] lazy val MethodTargetClass = requiredClass[meta.companionMethod] // TODO: module, moduleClass? package, packageObject? lazy val LanguageFeatureAnnot = requiredClass[meta.languageFeature] @@ -921,11 +921,21 @@ trait Definitions extends api.StandardDefinitions { // Trying to allow for deprecated locations sym.isAliasType && isMetaAnnotation(sym.info.typeSymbol) ) - lazy val metaAnnotations = Set[Symbol]( - FieldTargetClass, ParamTargetClass, - GetterTargetClass, SetterTargetClass, - BeanGetterTargetClass, BeanSetterTargetClass - ) + lazy val metaAnnotations: Set[Symbol] = getPackage("scala.annotation.meta").info.members filter (_ isSubClass StaticAnnotationClass) toSet + + // According to the scala.annotation.meta package object: + // * By default, annotations on (`val`-, `var`- or plain) constructor parameters + // * end up on the parameter, not on any other entity. Annotations on fields + // * by default only end up on the field. + def defaultAnnotationTarget(t: Tree): Symbol = t match { + case ClassDef(_, _, _, _) => ClassTargetClass + case ModuleDef(_, _, _) => ObjectTargetClass + case vd @ ValDef(_, _, _, _) if vd.symbol.isParamAccessor => ParamTargetClass + case vd @ ValDef(_, _, _, _) if vd.symbol.isValueParameter => ParamTargetClass + case ValDef(_, _, _, _) => FieldTargetClass + case DefDef(_, _, _, _, _, _) => MethodTargetClass + case _ => GetterTargetClass + } lazy val AnnotationDefaultAttr: ClassSymbol = { val attr = enterNewClass(RuntimePackageClass, tpnme.AnnotationDefaultATTR, List(AnnotationClass.tpe)) @@ -1060,8 +1070,7 @@ trait Definitions extends api.StandardDefinitions { AnyValClass, NullClass, NothingClass, - SingletonClass, - EqualsPatternClass + SingletonClass ) /** Lists core methods that don't have underlying bytecode, but are synthesized on-the-fly in every reflection universe */ lazy val syntheticCoreMethods = List( diff --git a/src/compiler/scala/tools/nsc/typechecker/Modes.scala b/src/reflect/scala/reflect/internal/Mode.scala index e1ee3c482a..850e3b5669 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Modes.scala +++ b/src/reflect/scala/reflect/internal/Mode.scala @@ -3,75 +3,76 @@ * @author Martin Odersky */ -package scala.tools.nsc -package typechecker +package scala.reflect +package internal + +object Mode { + private implicit def liftIntBitsToMode(bits: Int): Mode = apply(bits) + def apply(bits: Int): Mode = new Mode(bits) -/** Mode constants. - */ -trait Modes { /** NOmode, EXPRmode and PATTERNmode are mutually exclusive. */ - final val NOmode = 0x000 - final val EXPRmode = 0x001 - final val PATTERNmode = 0x002 + final val NOmode: Mode = 0x000 + final val EXPRmode: Mode = 0x001 + final val PATTERNmode: Mode = 0x002 /** TYPEmode needs a comment. <-- XXX. */ - final val TYPEmode = 0x004 + final val TYPEmode: Mode = 0x004 /** SCCmode is orthogonal to above. When set we are * in the this or super constructor call of a constructor. */ - final val SCCmode = 0x008 + final val SCCmode: Mode = 0x008 /** FUNmode is orthogonal to above. * When set we are looking for a method or constructor. */ - final val FUNmode = 0x010 + final val FUNmode: Mode = 0x010 /** POLYmode is orthogonal to above. * When set expression types can be polymorphic. */ - final val POLYmode = 0x020 + final val POLYmode: Mode = 0x020 /** QUALmode is orthogonal to above. When set * expressions may be packages and Java statics modules. */ - final val QUALmode = 0x040 + final val QUALmode: Mode = 0x040 /** TAPPmode is set for the function/type constructor * part of a type application. When set we do not decompose PolyTypes. */ - final val TAPPmode = 0x080 + final val TAPPmode: Mode = 0x080 /** SUPERCONSTRmode is set for the super * in a superclass constructor call super.<init>. */ - final val SUPERCONSTRmode = 0x100 + final val SUPERCONSTRmode: Mode = 0x100 /** SNDTRYmode indicates that an application is typed for the 2nd time. * In that case functions may no longer be coerced with implicit views. */ - final val SNDTRYmode = 0x200 + final val SNDTRYmode: Mode = 0x200 /** LHSmode is set for the left-hand side of an assignment. */ - final val LHSmode = 0x400 + final val LHSmode: Mode = 0x400 /** STARmode is set when star patterns are allowed. * (This was formerly called REGPATmode.) */ - final val STARmode = 0x1000 + final val STARmode: Mode = 0x1000 /** ALTmode is set when we are under a pattern alternative. */ - final val ALTmode = 0x2000 + final val ALTmode: Mode = 0x2000 /** HKmode is set when we are typing a higher-kinded type. * adapt should then check kind-arity based on the prototypical type's * kind arity. Type arguments should not be inferred. */ - final val HKmode = 0x4000 // @M: could also use POLYmode | TAPPmode + final val HKmode: Mode = 0x4000 // @M: could also use POLYmode | TAPPmode /** BYVALmode is set when we are typing an expression * that occurs in a by-value position. An expression e1 is in by-value @@ -80,39 +81,17 @@ trait Modes { * arguments or the conditional of an if-then-else clause. * This mode has been added to support continuations. */ - final val BYVALmode = 0x8000 + final val BYVALmode: Mode = 0x8000 /** TYPEPATmode is set when we are typing a type in a pattern. */ - final val TYPEPATmode = 0x10000 + final val TYPEPATmode: Mode = 0x10000 /** RETmode is set when we are typing a return expression. */ - final val RETmode = 0x20000 - - final private val StickyModes = EXPRmode | PATTERNmode | TYPEmode | ALTmode - - final def onlyStickyModes(mode: Int) = - mode & StickyModes - - final def forFunMode(mode: Int) = - mode & (StickyModes | SCCmode) | FUNmode | POLYmode | BYVALmode - - final def forTypeMode(mode: Int) = - if (inAnyMode(mode, PATTERNmode | TYPEPATmode)) TYPEmode | TYPEPATmode - else TYPEmode + final val RETmode: Mode = 0x20000 - final def inAllModes(mode: Int, required: Int) = (mode & required) == required - final def inAnyMode(mode: Int, required: Int) = (mode & required) != 0 - final def inNoModes(mode: Int, prohibited: Int) = (mode & prohibited) == 0 - final def inHKMode(mode: Int) = (mode & HKmode) != 0 - final def inFunMode(mode: Int) = (mode & FUNmode) != 0 - final def inPolyMode(mode: Int) = (mode & POLYmode) != 0 - final def inPatternMode(mode: Int) = (mode & PATTERNmode) != 0 - final def inPatternNotFunMode(mode: Int) = inPatternMode(mode) && !inFunMode(mode) - final def inExprModeOr(mode: Int, others: Int) = (mode & (EXPRmode | others)) != 0 - final def inExprModeButNot(mode: Int, prohibited: Int) = - (mode & (EXPRmode | prohibited)) == EXPRmode + final private val StickyModes: Mode = EXPRmode | PATTERNmode | TYPEmode | ALTmode /** Translates a mask of mode flags into something readable. */ @@ -134,8 +113,37 @@ trait Modes { (1 << 14) -> "HKmode", (1 << 15) -> "BYVALmode", (1 << 16) -> "TYPEPATmode" - ) - def modeString(mode: Int): String = - if (mode == 0) "NOmode" - else (modeNameMap filterKeys (bit => inAllModes(mode, bit))).values mkString " " + ).map({ case (k, v) => Mode(k) -> v }) +} +import Mode._ + +final class Mode private (val bits: Int) extends AnyVal { + def &(other: Mode): Mode = new Mode(bits & other.bits) + def |(other: Mode): Mode = new Mode(bits | other.bits) + def &~(other: Mode): Mode = new Mode(bits & ~(other.bits)) + + def onlySticky = this & Mode.StickyModes + def forFunMode = this & (Mode.StickyModes | SCCmode) | FUNmode | POLYmode | BYVALmode + def forTypeMode = + if (inAny(PATTERNmode | TYPEPATmode)) TYPEmode | TYPEPATmode + else TYPEmode + + def inAll(required: Mode) = (this & required) == required + def inAny(required: Mode) = (this & required) !=NOmode + def inNone(prohibited: Mode) = (this & prohibited) == NOmode + def inHKMode = inAll(HKmode) + def inFunMode = inAll(FUNmode) + def inPolyMode = inAll(POLYmode) + def inPatternMode = inAll(PATTERNmode) + def inExprMode = inAll(EXPRmode) + def inByValMode = inAll(BYVALmode) + def inRetMode = inAll(RETmode) + + def inPatternNotFunMode = inPatternMode && !inFunMode + def inExprModeOr(others: Mode) = inAny(EXPRmode | others) + def inExprModeButNot(prohibited: Mode) = inAll(EXPRmode) && inNone(prohibited) + + override def toString = + if (bits == 0) "NOmode" + else (modeNameMap filterKeys inAll).values.toList.sorted mkString " " } diff --git a/src/reflect/scala/reflect/internal/StdAttachments.scala b/src/reflect/scala/reflect/internal/StdAttachments.scala index b782353ed3..6c5bbc9774 100644 --- a/src/reflect/scala/reflect/internal/StdAttachments.scala +++ b/src/reflect/scala/reflect/internal/StdAttachments.scala @@ -29,17 +29,4 @@ trait StdAttachments { * Therefore we need this hack (see `Reshape.toPreTyperTypeTree` for a detailed explanation). */ case class CompoundTypeTreeOriginalAttachment(parents: List[Tree], stats: List[Tree]) - - /** Is added by the macro engine to the results of macro expansions. - * Stores the original expandee as it entered the `macroExpand` function. - */ - case class MacroExpansionAttachment(original: Tree) - - /** When present, suppresses macro expansion for the host. - * This is occasionally necessary, e.g. to prohibit eta-expansion of macros. - * - * Does not affect expandability of child nodes, there's context.withMacrosDisabled for that - * (but think thrice before using that API - see the discussion at https://github.com/scala/scala/pull/1639). - */ - case object SuppressMacroExpansionAttachment } diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index 10dd2c82aa..3d1701386e 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -200,7 +200,6 @@ trait StdNames { protected implicit def createNameType(name: String): TypeName = newTypeNameCached(name) final val BYNAME_PARAM_CLASS_NAME: NameType = "<byname>" - final val EQUALS_PATTERN_NAME: NameType = "<equals>" final val JAVA_REPEATED_PARAM_CLASS_NAME: NameType = "<repeated...>" final val LOCAL_CHILD: NameType = "<local child>" final val REFINE_CLASS_NAME: NameType = "<refinement>" diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 0127bd988b..2d42d2df58 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -654,7 +654,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => info.firstParent.typeSymbol == AnyValClass && !isPrimitiveValueClass final def isMethodWithExtension = - isMethod && owner.isDerivedValueClass && !isParamAccessor && !isConstructor && !hasFlag(SUPERACCESSOR) && !isTermMacro + isMethod && owner.isDerivedValueClass && !isParamAccessor && !isConstructor && !hasFlag(SUPERACCESSOR) && !isMacro final def isAnonymousFunction = isSynthetic && (name containsName tpnme.ANON_FUN_NAME) final def isDefinedInPackage = effectiveOwner.isPackageClass @@ -2241,7 +2241,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => private case class SymbolKind(accurate: String, sanitized: String, abbreviation: String) private def symbolKind: SymbolKind = { var kind = - if (isTermMacro) ("macro method", "macro method", "MAC") + if (isTermMacro) ("term macro", "macro method", "MACM") else if (isInstanceOf[FreeTermSymbol]) ("free term", "free term", "FTE") else if (isInstanceOf[FreeTypeSymbol]) ("free type", "free type", "FTY") else if (isPackage) ("package", "package", "PK") diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala index 9614513458..032a4aebef 100644 --- a/src/reflect/scala/reflect/internal/TreeInfo.scala +++ b/src/reflect/scala/reflect/internal/TreeInfo.scala @@ -735,4 +735,15 @@ abstract class TreeInfo { case tree: RefTree => true case _ => false }) + + def isMacroApplication(tree: Tree): Boolean = + !tree.isDef && tree.symbol != null && tree.symbol.isMacro && !tree.symbol.isErroneous + + def isMacroApplicationOrBlock(tree: Tree): Boolean = tree match { + case Block(_, expr) => isMacroApplicationOrBlock(expr) + case tree => isMacroApplication(tree) + } + + def isNonTrivialMacroApplication(tree: Tree): Boolean = + isMacroApplication(tree) && dissectApplied(tree).core != tree } diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index 308ab93c07..3c2249bfb5 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -164,6 +164,9 @@ trait Trees extends api.Trees { self: SymbolTable => override def substituteThis(clazz: Symbol, to: Tree): Tree = new ThisSubstituter(clazz, to) transform this + def replace(from: Tree, to: Tree): Tree = + new TreeReplacer(from, to, positionAware = false) transform this + def hasSymbolWhich(f: Symbol => Boolean) = (symbol ne null) && (symbol ne NoSymbol) && f(symbol) @@ -1381,6 +1384,16 @@ trait Trees extends api.Trees { self: SymbolTable => if (tree eq orig) super.transform(tree) else tree } + + /** A transformer that replaces tree `from` with tree `to` in a given tree */ + class TreeReplacer(from: Tree, to: Tree, positionAware: Boolean) extends Transformer { + override def transform(t: Tree): Tree = { + if (t == from) to + else if (!positionAware || (t.pos includes from.pos) || t.pos.isTransparent) super.transform(t) + else t + } + } + // Create a readable string describing a substitution. private def substituterString(fromStr: String, toStr: String, from: List[Any], to: List[Any]): String = { "subst[%s, %s](%s)".format(fromStr, toStr, (from, to).zipped map (_ + " -> " + _) mkString ", ") diff --git a/src/reflect/scala/reflect/macros/Enclosures.scala b/src/reflect/scala/reflect/macros/Enclosures.scala index 1e366ccbc3..723b94016d 100644 --- a/src/reflect/scala/reflect/macros/Enclosures.scala +++ b/src/reflect/scala/reflect/macros/Enclosures.scala @@ -17,6 +17,19 @@ trait Enclosures { */ def macroApplication: Tree + /** The semantic role that `macroApplication` plays in the code. + */ + type MacroRole + + /** The role that represents an application of a term macro, + * e.g. `M(2)(3)` in `val x = M(2)(3)` or `M(a, b)` in `x match { case x @ M(a, b) => }`. + */ + def APPLY_ROLE: MacroRole + + /** The semantic role that `macroApplication` plays in the code. + */ + def macroRole: MacroRole + /** Contexts that represent macros in-flight, including the current one. Very much like a stack trace, but for macros only. * Can be useful for interoperating with other macros and for imposing compiler-friendly limits on macro expansion. * diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index 67b24cbdea..cdb9e7159c 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -319,7 +319,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni lazy val bytecodefulObjectMethods = Set[Symbol](Object_clone, Object_equals, Object_finalize, Object_hashCode, Object_toString, Object_notify, Object_notifyAll) ++ ObjectClass.info.member(nme.wait_).asTerm.alternatives.map(_.asMethod) private def isBytecodelessMethod(meth: MethodSymbol): Boolean = { - if (isGetClass(meth) || isStringConcat(meth) || meth.owner.isPrimitiveValueClass || meth == Predef_classOf || meth.isTermMacro) return true + if (isGetClass(meth) || isStringConcat(meth) || meth.owner.isPrimitiveValueClass || meth == Predef_classOf || meth.isMacro) return true bytecodelessMethodOwners(meth.owner) && !bytecodefulObjectMethods(meth) } @@ -457,7 +457,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni case sym if isStringConcat(sym) => receiver.toString + objArg0 case sym if sym.owner.isPrimitiveValueClass => invokePrimitiveMethod case sym if sym == Predef_classOf => fail("Predef.classOf is a compile-time function") - case sym if sym.isTermMacro => fail(s"${symbol.fullName} is a macro, i.e. a compile-time function") + case sym if sym.isMacro => fail(s"${symbol.fullName} is a macro, i.e. a compile-time function") case _ => abort(s"unsupported symbol $symbol when invoking $this") } } diff --git a/src/swing/scala/swing/SwingActor.scala b/src/swing/scala/swing/SwingActor.scala deleted file mode 100644 index c665fa4c00..0000000000 --- a/src/swing/scala/swing/SwingActor.scala +++ /dev/null @@ -1,31 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.swing - -// Dummy to keep ant from recompiling on every run. -trait SwingActor { } - -/*object SwingActor { - /** - * Similar to Actor.actor, but creates an instance of a SwingActor. - */ - def apply(body: => Unit): Actor = - new SwingActor { def act() = body }.start() -} - -/** - * An actor that runs on the Swing event dispatching thread (EDT). - */ -abstract class SwingActor extends Actor { - override val scheduler = new SchedulerAdapter { - def execute(op: =>Unit) = Swing onEDT op - def onTerminate(a: Actor)(op: => Unit) {} - def terminated(a: Actor) {} - } -}*/ diff --git a/src/swing/scala/swing/SwingWorker.scala b/src/swing/scala/swing/SwingWorker.scala deleted file mode 100644 index 0e514e38a7..0000000000 --- a/src/swing/scala/swing/SwingWorker.scala +++ /dev/null @@ -1,21 +0,0 @@ -package scala.swing - -import scala.actors._ - -object SwingWorker { - -} - -abstract class SwingWorker extends Actor { - def queue() { - - } - - def done() { - - } - - private var _cancelled = false - def cancelled: Boolean = _cancelled - def cancelled_=(b: Boolean) { _cancelled = b } -}
\ No newline at end of file diff --git a/test/disabled/presentation/simple-tests.check b/test/disabled/presentation/simple-tests.check index cdb80ed987..0f72cb5ab9 100644 --- a/test/disabled/presentation/simple-tests.check +++ b/test/disabled/presentation/simple-tests.check @@ -187,8 +187,6 @@ TypeMember(value Xshowobj,Tester.this.settings.StringSetting,false,true,<none>) TypeMember(value Xshowtrees,Tester.this.settings.BooleanSetting,false,true,<none>) TypeMember(value Xwarnfatal,Tester.this.settings.BooleanSetting,false,true,<none>) TypeMember(value Xwarninit,Tester.this.settings.BooleanSetting,false,true,<none>) -TypeMember(value Ybuilderdebug,Tester.this.settings.ChoiceSetting,false,true,<none>) -TypeMember(value Ybuildmanagerdebug,Tester.this.settings.BooleanSetting,false,true,<none>) TypeMember(value Ycompacttrees,Tester.this.settings.BooleanSetting,false,true,<none>) TypeMember(value Ycompletion,Tester.this.settings.BooleanSetting,false,true,<none>) TypeMember(value YdepMethTpes,Tester.this.settings.BooleanSetting,false,true,<none>) diff --git a/test/files/buildmanager/annotated/A.scala b/test/files/buildmanager/annotated/A.scala deleted file mode 100644 index 4130cf21ec..0000000000 --- a/test/files/buildmanager/annotated/A.scala +++ /dev/null @@ -1 +0,0 @@ -case class A[T](x: String, y: T) diff --git a/test/files/buildmanager/annotated/annotated.check b/test/files/buildmanager/annotated/annotated.check deleted file mode 100644 index ce92c9a294..0000000000 --- a/test/files/buildmanager/annotated/annotated.check +++ /dev/null @@ -1,6 +0,0 @@ -builder > A.scala -compiling Set(A.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(class A -> List(), object A -> List()) diff --git a/test/files/buildmanager/annotated/annotated.test b/test/files/buildmanager/annotated/annotated.test deleted file mode 100644 index 392e0d365f..0000000000 --- a/test/files/buildmanager/annotated/annotated.test +++ /dev/null @@ -1,2 +0,0 @@ ->>compile A.scala ->>compile A.scala diff --git a/test/files/buildmanager/freshnames/A.scala b/test/files/buildmanager/freshnames/A.scala deleted file mode 100644 index e8ab26ca1e..0000000000 --- a/test/files/buildmanager/freshnames/A.scala +++ /dev/null @@ -1,16 +0,0 @@ -abstract class A { - - var t: List[B] - - def foo(n: String): Option[B] = { - t.reverse find (_.names contains n) - } - - def bar(n: Int): Option[B] = { - t.reverse find (_.names contains n) - } -} - -//class A -case class B(names: List[String]) - diff --git a/test/files/buildmanager/freshnames/B.scala b/test/files/buildmanager/freshnames/B.scala deleted file mode 100644 index d700225c08..0000000000 --- a/test/files/buildmanager/freshnames/B.scala +++ /dev/null @@ -1,4 +0,0 @@ -abstract class C extends A { - def test(n: Int) = bar(n) -} - diff --git a/test/files/buildmanager/freshnames/freshnames.check b/test/files/buildmanager/freshnames/freshnames.check deleted file mode 100644 index 9f05fb8a36..0000000000 --- a/test/files/buildmanager/freshnames/freshnames.check +++ /dev/null @@ -1,6 +0,0 @@ -builder > B.scala A.scala -compiling Set(A.scala, B.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(class A -> List(), class B -> List(), object B -> List()) diff --git a/test/files/buildmanager/freshnames/freshnames.test b/test/files/buildmanager/freshnames/freshnames.test deleted file mode 100644 index 20b20298f9..0000000000 --- a/test/files/buildmanager/freshnames/freshnames.test +++ /dev/null @@ -1,2 +0,0 @@ ->>compile B.scala A.scala ->>compile A.scala diff --git a/test/files/buildmanager/infer/A.scala b/test/files/buildmanager/infer/A.scala deleted file mode 100644 index 46b5391609..0000000000 --- a/test/files/buildmanager/infer/A.scala +++ /dev/null @@ -1,16 +0,0 @@ -class Foo(flag: Boolean) { - val classpath = - if (flag) - new AClasspath - else - new BClasspath -} - -class AClasspath extends MergedClasspath[A] - -class BClasspath extends MergedClasspath[B] - -abstract class MergedClasspath[T] - -class A -class B diff --git a/test/files/buildmanager/infer/infer.check b/test/files/buildmanager/infer/infer.check deleted file mode 100644 index 1f736977ff..0000000000 --- a/test/files/buildmanager/infer/infer.check +++ /dev/null @@ -1,6 +0,0 @@ -builder > A.scala -compiling Set(A.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(class A -> List(), class AClasspath -> List(), class B -> List(), class BClasspath -> List(), class Foo -> List(), class MergedClasspath -> List()) diff --git a/test/files/buildmanager/infer/infer.test b/test/files/buildmanager/infer/infer.test deleted file mode 100644 index 392e0d365f..0000000000 --- a/test/files/buildmanager/infer/infer.test +++ /dev/null @@ -1,2 +0,0 @@ ->>compile A.scala ->>compile A.scala diff --git a/test/files/buildmanager/namesdefaults/defparam-use.scala b/test/files/buildmanager/namesdefaults/defparam-use.scala deleted file mode 100644 index 5b5bbb3f4e..0000000000 --- a/test/files/buildmanager/namesdefaults/defparam-use.scala +++ /dev/null @@ -1,5 +0,0 @@ - -object Test extends App { - val outer = new Outer - new outer.Inner -} diff --git a/test/files/buildmanager/namesdefaults/defparam.scala b/test/files/buildmanager/namesdefaults/defparam.scala deleted file mode 100644 index d817c719ab..0000000000 --- a/test/files/buildmanager/namesdefaults/defparam.scala +++ /dev/null @@ -1,7 +0,0 @@ -class Outer { - - class Inner(val x: List[Int] = Nil) - -// lazy val Inner = "abc" -} - diff --git a/test/files/buildmanager/namesdefaults/namesdefaults.check b/test/files/buildmanager/namesdefaults/namesdefaults.check deleted file mode 100644 index 4a94d1fb55..0000000000 --- a/test/files/buildmanager/namesdefaults/namesdefaults.check +++ /dev/null @@ -1,9 +0,0 @@ -builder > defparam.scala defparam-use.scala -compiling Set(defparam-use.scala, defparam.scala) -Changes: Map() -builder > defparam-use.scala -compiling Set(defparam-use.scala) -Changes: Map(class Test$delayedInit$body -> List(), object Test -> List()) -builder > defparam-use.scala -compiling Set(defparam-use.scala) -Changes: Map(class Test$delayedInit$body -> List(), object Test -> List()) diff --git a/test/files/buildmanager/namesdefaults/namesdefaults.test b/test/files/buildmanager/namesdefaults/namesdefaults.test deleted file mode 100644 index 84ccc36bc3..0000000000 --- a/test/files/buildmanager/namesdefaults/namesdefaults.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile defparam.scala defparam-use.scala ->>compile defparam-use.scala ->>compile defparam-use.scala diff --git a/test/files/buildmanager/simpletest/A.scala b/test/files/buildmanager/simpletest/A.scala deleted file mode 100644 index ef704706bb..0000000000 --- a/test/files/buildmanager/simpletest/A.scala +++ /dev/null @@ -1,3 +0,0 @@ -class A { - def foo = 2 -} diff --git a/test/files/buildmanager/simpletest/B.scala b/test/files/buildmanager/simpletest/B.scala deleted file mode 100644 index 364dc6e4cb..0000000000 --- a/test/files/buildmanager/simpletest/B.scala +++ /dev/null @@ -1,3 +0,0 @@ -class B extends A { - override def foo = 2 -} diff --git a/test/files/buildmanager/simpletest/simpletest.changes/A1.scala b/test/files/buildmanager/simpletest/simpletest.changes/A1.scala deleted file mode 100644 index 83d15dc739..0000000000 --- a/test/files/buildmanager/simpletest/simpletest.changes/A1.scala +++ /dev/null @@ -1 +0,0 @@ -class A diff --git a/test/files/buildmanager/simpletest/simpletest.check b/test/files/buildmanager/simpletest/simpletest.check deleted file mode 100644 index 95ea2c4c0d..0000000000 --- a/test/files/buildmanager/simpletest/simpletest.check +++ /dev/null @@ -1,11 +0,0 @@ -builder > A.scala B.scala -compiling Set(A.scala, B.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(class A -> List(Removed(Definition(A.foo)))) -invalidate B.scala because inherited method removed [Removed(Definition(A.foo))] -compiling Set(B.scala) -B.scala:2: error: method foo overrides nothing - override def foo = 2 - ^ diff --git a/test/files/buildmanager/simpletest/simpletest.test b/test/files/buildmanager/simpletest/simpletest.test deleted file mode 100644 index 2c0be1502f..0000000000 --- a/test/files/buildmanager/simpletest/simpletest.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile A.scala B.scala ->>update A.scala=>A1.scala ->>compile A.scala diff --git a/test/files/buildmanager/t2280/A.scala b/test/files/buildmanager/t2280/A.scala deleted file mode 100644 index 5febadeb06..0000000000 --- a/test/files/buildmanager/t2280/A.scala +++ /dev/null @@ -1 +0,0 @@ -class A extends B diff --git a/test/files/buildmanager/t2280/B.java b/test/files/buildmanager/t2280/B.java deleted file mode 100644 index aef8e106e9..0000000000 --- a/test/files/buildmanager/t2280/B.java +++ /dev/null @@ -1,2 +0,0 @@ -public class B {} - diff --git a/test/files/buildmanager/t2280/t2280.check b/test/files/buildmanager/t2280/t2280.check deleted file mode 100644 index 7ea7511c63..0000000000 --- a/test/files/buildmanager/t2280/t2280.check +++ /dev/null @@ -1,6 +0,0 @@ -builder > A.scala B.java -compiling Set(A.scala, B.java) -Changes: Map() -builder > B.java -compiling Set(B.java) -Changes: Map(class B -> List()) diff --git a/test/files/buildmanager/t2280/t2280.test b/test/files/buildmanager/t2280/t2280.test deleted file mode 100644 index 2eda777853..0000000000 --- a/test/files/buildmanager/t2280/t2280.test +++ /dev/null @@ -1,2 +0,0 @@ ->>compile A.scala B.java ->>compile B.java diff --git a/test/files/buildmanager/t2556_1/A.scala b/test/files/buildmanager/t2556_1/A.scala deleted file mode 100644 index c6e200b217..0000000000 --- a/test/files/buildmanager/t2556_1/A.scala +++ /dev/null @@ -1,3 +0,0 @@ -class A { - def x(i: Int) = i+"3" -} diff --git a/test/files/buildmanager/t2556_1/B.scala b/test/files/buildmanager/t2556_1/B.scala deleted file mode 100644 index 8529587b56..0000000000 --- a/test/files/buildmanager/t2556_1/B.scala +++ /dev/null @@ -1,3 +0,0 @@ -class B extends A { - def x(s: String) = s+"5" -} diff --git a/test/files/buildmanager/t2556_1/t2556_1.changes/A2.scala b/test/files/buildmanager/t2556_1/t2556_1.changes/A2.scala deleted file mode 100644 index 4ac1045e13..0000000000 --- a/test/files/buildmanager/t2556_1/t2556_1.changes/A2.scala +++ /dev/null @@ -1,4 +0,0 @@ -class A { - def x(i: String) = i+"3" -} - diff --git a/test/files/buildmanager/t2556_1/t2556_1.check b/test/files/buildmanager/t2556_1/t2556_1.check deleted file mode 100644 index 2e501c8f6f..0000000000 --- a/test/files/buildmanager/t2556_1/t2556_1.check +++ /dev/null @@ -1,12 +0,0 @@ -builder > A.scala B.scala -compiling Set(A.scala, B.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(class A -> List(Changed(Definition(A.x))[method x changed from (i: Int)String to (i: String)String flags: <method>])) -invalidate B.scala because inherited method changed [Changed(Definition(A.x))[method x changed from (i: Int)String to (i: String)String flags: <method>]] -compiling Set(B.scala) -B.scala:2: error: overriding method x in class A of type (i: String)String; - method x needs `override' modifier - def x(s: String) = s+"5" - ^ diff --git a/test/files/buildmanager/t2556_1/t2556_1.test b/test/files/buildmanager/t2556_1/t2556_1.test deleted file mode 100644 index 6f3bd03361..0000000000 --- a/test/files/buildmanager/t2556_1/t2556_1.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile A.scala B.scala ->>update A.scala=>A2.scala ->>compile A.scala diff --git a/test/files/buildmanager/t2556_2/A.scala b/test/files/buildmanager/t2556_2/A.scala deleted file mode 100644 index b8da5c8fb1..0000000000 --- a/test/files/buildmanager/t2556_2/A.scala +++ /dev/null @@ -1,4 +0,0 @@ -class A { - def x(i: Int) = i+"3" -} - diff --git a/test/files/buildmanager/t2556_2/B.scala b/test/files/buildmanager/t2556_2/B.scala deleted file mode 100644 index 80ff25d0ca..0000000000 --- a/test/files/buildmanager/t2556_2/B.scala +++ /dev/null @@ -1,2 +0,0 @@ -class B extends A - diff --git a/test/files/buildmanager/t2556_2/C.scala b/test/files/buildmanager/t2556_2/C.scala deleted file mode 100644 index 0ab13e3757..0000000000 --- a/test/files/buildmanager/t2556_2/C.scala +++ /dev/null @@ -1,4 +0,0 @@ -class C extends B { - def x(s: String) = s+"5" -} - diff --git a/test/files/buildmanager/t2556_2/t2556_2.changes/A2.scala b/test/files/buildmanager/t2556_2/t2556_2.changes/A2.scala deleted file mode 100644 index 4ac1045e13..0000000000 --- a/test/files/buildmanager/t2556_2/t2556_2.changes/A2.scala +++ /dev/null @@ -1,4 +0,0 @@ -class A { - def x(i: String) = i+"3" -} - diff --git a/test/files/buildmanager/t2556_2/t2556_2.check b/test/files/buildmanager/t2556_2/t2556_2.check deleted file mode 100644 index cae4f72212..0000000000 --- a/test/files/buildmanager/t2556_2/t2556_2.check +++ /dev/null @@ -1,13 +0,0 @@ -builder > A.scala B.scala C.scala -compiling Set(A.scala, B.scala, C.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(class A -> List(Changed(Definition(A.x))[method x changed from (i: Int)String to (i: String)String flags: <method>])) -invalidate B.scala because inherited method changed [Changed(Definition(A.x))[method x changed from (i: Int)String to (i: String)String flags: <method>]] -invalidate C.scala because inherited method changed [Changed(Definition(A.x))[method x changed from (i: Int)String to (i: String)String flags: <method>]] -compiling Set(B.scala, C.scala) -C.scala:2: error: overriding method x in class A of type (i: String)String; - method x needs `override' modifier - def x(s: String) = s+"5" - ^ diff --git a/test/files/buildmanager/t2556_2/t2556_2.test b/test/files/buildmanager/t2556_2/t2556_2.test deleted file mode 100644 index 9f31bb6409..0000000000 --- a/test/files/buildmanager/t2556_2/t2556_2.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile A.scala B.scala C.scala ->>update A.scala=>A2.scala ->>compile A.scala diff --git a/test/files/buildmanager/t2556_3/A.scala b/test/files/buildmanager/t2556_3/A.scala deleted file mode 100644 index 089a05f493..0000000000 --- a/test/files/buildmanager/t2556_3/A.scala +++ /dev/null @@ -1,5 +0,0 @@ -class A { - def x = 3 -} -class B extends A - diff --git a/test/files/buildmanager/t2556_3/B.scala b/test/files/buildmanager/t2556_3/B.scala deleted file mode 100644 index 0ec5ae4b55..0000000000 --- a/test/files/buildmanager/t2556_3/B.scala +++ /dev/null @@ -1,5 +0,0 @@ -object E { - def main(args: Array[String]) = - println( (new C).x ) -} - diff --git a/test/files/buildmanager/t2556_3/C.scala b/test/files/buildmanager/t2556_3/C.scala deleted file mode 100644 index 403df8455e..0000000000 --- a/test/files/buildmanager/t2556_3/C.scala +++ /dev/null @@ -1,2 +0,0 @@ -class C extends B - diff --git a/test/files/buildmanager/t2556_3/t2556_3.changes/A2.scala b/test/files/buildmanager/t2556_3/t2556_3.changes/A2.scala deleted file mode 100644 index 21cb2779f9..0000000000 --- a/test/files/buildmanager/t2556_3/t2556_3.changes/A2.scala +++ /dev/null @@ -1,5 +0,0 @@ -class A { - def x = 3 -} -class B - diff --git a/test/files/buildmanager/t2556_3/t2556_3.check b/test/files/buildmanager/t2556_3/t2556_3.check deleted file mode 100644 index 34f90f7f9b..0000000000 --- a/test/files/buildmanager/t2556_3/t2556_3.check +++ /dev/null @@ -1,18 +0,0 @@ -builder > A.scala B.scala C.scala -compiling Set(A.scala, B.scala, C.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(class A -> List(), class B -> List(Changed(Class(B))[List((A,Object))])) -invalidate C.scala because parents have changed [Changed(Class(B))[List((A,Object))]] -invalidate B.scala because it references invalid (no longer inherited) definition [ParentChanged(Class(C))] -compiling Set(B.scala, C.scala) -B.scala:3: error: type mismatch; - found : C - required: ?{def x: ?} -Note that implicit conversions are not applicable because they are ambiguous: - both method any2Ensuring in object Predef of type [A](x: A)Ensuring[A] - and method any2ArrowAssoc in object Predef of type [A](x: A)ArrowAssoc[A] - are possible conversion functions from C to ?{def x: ?} - println( (new C).x ) - ^ diff --git a/test/files/buildmanager/t2556_3/t2556_3.test b/test/files/buildmanager/t2556_3/t2556_3.test deleted file mode 100644 index 9f31bb6409..0000000000 --- a/test/files/buildmanager/t2556_3/t2556_3.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile A.scala B.scala C.scala ->>update A.scala=>A2.scala ->>compile A.scala diff --git a/test/files/buildmanager/t2557/A.scala b/test/files/buildmanager/t2557/A.scala deleted file mode 100644 index 3be55f19a6..0000000000 --- a/test/files/buildmanager/t2557/A.scala +++ /dev/null @@ -1,4 +0,0 @@ -trait A { - def x = 3 -} - diff --git a/test/files/buildmanager/t2557/B.scala b/test/files/buildmanager/t2557/B.scala deleted file mode 100644 index ea86a90079..0000000000 --- a/test/files/buildmanager/t2557/B.scala +++ /dev/null @@ -1,4 +0,0 @@ -trait B extends A { - override def x = super.x * 2 -} - diff --git a/test/files/buildmanager/t2557/C.scala b/test/files/buildmanager/t2557/C.scala deleted file mode 100644 index dd575ac38d..0000000000 --- a/test/files/buildmanager/t2557/C.scala +++ /dev/null @@ -1,3 +0,0 @@ -trait C extends A { - override def x = super.x + 5 -} diff --git a/test/files/buildmanager/t2557/D.scala b/test/files/buildmanager/t2557/D.scala deleted file mode 100644 index 4e662a80ce..0000000000 --- a/test/files/buildmanager/t2557/D.scala +++ /dev/null @@ -1 +0,0 @@ -trait D extends C with B diff --git a/test/files/buildmanager/t2557/E.scala b/test/files/buildmanager/t2557/E.scala deleted file mode 100644 index 2aee552675..0000000000 --- a/test/files/buildmanager/t2557/E.scala +++ /dev/null @@ -1 +0,0 @@ -trait E extends D diff --git a/test/files/buildmanager/t2557/F.scala b/test/files/buildmanager/t2557/F.scala deleted file mode 100644 index e1996704e7..0000000000 --- a/test/files/buildmanager/t2557/F.scala +++ /dev/null @@ -1,4 +0,0 @@ -object F extends E { - def main(args: Array[String]) = - println(x) -} diff --git a/test/files/buildmanager/t2557/t2557.changes/D2.scala b/test/files/buildmanager/t2557/t2557.changes/D2.scala deleted file mode 100644 index 67295f8e6d..0000000000 --- a/test/files/buildmanager/t2557/t2557.changes/D2.scala +++ /dev/null @@ -1,2 +0,0 @@ -trait D extends B with C - diff --git a/test/files/buildmanager/t2557/t2557.check b/test/files/buildmanager/t2557/t2557.check deleted file mode 100644 index 736ef3645e..0000000000 --- a/test/files/buildmanager/t2557/t2557.check +++ /dev/null @@ -1,10 +0,0 @@ -builder > A.scala B.scala C.scala D.scala E.scala F.scala -compiling Set(A.scala, B.scala, C.scala, D.scala, E.scala, F.scala) -Changes: Map() -builder > D.scala -compiling Set(D.scala) -Changes: Map(trait D -> List(Changed(Class(D))[List((Object,Object), (C,B), (B,C))])) -invalidate E.scala because parents have changed [Changed(Class(D))[List((Object,Object), (C,B), (B,C))]] -invalidate F.scala because parents have changed [Changed(Class(D))[List((Object,Object), (C,B), (B,C))]] -compiling Set(E.scala, F.scala) -Changes: Map(object F -> List(), trait E -> List()) diff --git a/test/files/buildmanager/t2557/t2557.test b/test/files/buildmanager/t2557/t2557.test deleted file mode 100644 index 6b0103092f..0000000000 --- a/test/files/buildmanager/t2557/t2557.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile A.scala B.scala C.scala D.scala E.scala F.scala ->>update D.scala=>D2.scala ->>compile D.scala diff --git a/test/files/buildmanager/t2559/A.scala b/test/files/buildmanager/t2559/A.scala deleted file mode 100644 index fb4f6e3545..0000000000 --- a/test/files/buildmanager/t2559/A.scala +++ /dev/null @@ -1,5 +0,0 @@ -sealed trait A -class B extends A -class C extends A -//class E extends A - diff --git a/test/files/buildmanager/t2559/D.scala b/test/files/buildmanager/t2559/D.scala deleted file mode 100644 index 62dc5427f9..0000000000 --- a/test/files/buildmanager/t2559/D.scala +++ /dev/null @@ -1,4 +0,0 @@ -object D { - def x(a: A) = if (a.isInstanceOf[B] || a.isInstanceOf[C]) () -} - diff --git a/test/files/buildmanager/t2559/t2559.changes/A2.scala b/test/files/buildmanager/t2559/t2559.changes/A2.scala deleted file mode 100644 index 8e90594e2c..0000000000 --- a/test/files/buildmanager/t2559/t2559.changes/A2.scala +++ /dev/null @@ -1,5 +0,0 @@ -sealed trait A -class B extends A -class C extends A -class E extends A - diff --git a/test/files/buildmanager/t2559/t2559.check b/test/files/buildmanager/t2559/t2559.check deleted file mode 100644 index 4d43838cf5..0000000000 --- a/test/files/buildmanager/t2559/t2559.check +++ /dev/null @@ -1,9 +0,0 @@ -builder > A.scala D.scala -compiling Set(A.scala, D.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(class B -> List(), class C -> List(), class E -> List(Changed(Class(A))[class E extends a sealed trait A]), trait A -> List()) -invalidate D.scala because it references changed class [Changed(Class(A))[class E extends a sealed trait A]] -compiling Set(D.scala) -Changes: Map(object D -> List()) diff --git a/test/files/buildmanager/t2559/t2559.test b/test/files/buildmanager/t2559/t2559.test deleted file mode 100644 index b787c5b39f..0000000000 --- a/test/files/buildmanager/t2559/t2559.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile A.scala D.scala ->>update A.scala=>A2.scala ->>compile A.scala diff --git a/test/files/buildmanager/t2562/A.scala b/test/files/buildmanager/t2562/A.scala deleted file mode 100644 index 740cd1e868..0000000000 --- a/test/files/buildmanager/t2562/A.scala +++ /dev/null @@ -1,7 +0,0 @@ -object A -{ - def x0 = B.x0 - def x1 = B.x1 - def x2 = B.x2 - def x3 = 3 -} diff --git a/test/files/buildmanager/t2562/B.scala b/test/files/buildmanager/t2562/B.scala deleted file mode 100644 index a524e5cc84..0000000000 --- a/test/files/buildmanager/t2562/B.scala +++ /dev/null @@ -1,8 +0,0 @@ -object B -{ - def x0 = A.x1 - def x1 = A.x2 - def x2 = A.x3 -} - - diff --git a/test/files/buildmanager/t2562/t2562.changes/A2.scala b/test/files/buildmanager/t2562/t2562.changes/A2.scala deleted file mode 100644 index c560e1e816..0000000000 --- a/test/files/buildmanager/t2562/t2562.changes/A2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object A -{ - def x0 = B.x0 - def x1 = B.x1 - def x2 = B.x2 - def x3 = "3" -} - diff --git a/test/files/buildmanager/t2562/t2562.check b/test/files/buildmanager/t2562/t2562.check deleted file mode 100644 index 74575f28ea..0000000000 --- a/test/files/buildmanager/t2562/t2562.check +++ /dev/null @@ -1,12 +0,0 @@ -builder > A.scala B.scala -compiling Set(A.scala, B.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(object A -> List(Changed(Definition(A.x3))[method x3 changed from ()Int to ()String flags: <method> <triedcooking>])) -invalidate B.scala because it references changed definition [Changed(Definition(A.x3))[method x3 changed from ()Int to ()String flags: <method> <triedcooking>]] -compiling Set(B.scala) -Changes: Map(object B -> List(Changed(Definition(B.x2))[method x2 changed from ()Int to ()String flags: <method> <triedcooking>])) -invalidate A.scala because it references changed definition [Changed(Definition(B.x2))[method x2 changed from ()Int to ()String flags: <method> <triedcooking>]] -compiling Set(A.scala, B.scala) -Changes: Map(object A -> List(Changed(Definition(A.x0))[method x0 changed from ()Int to ()String flags: <method>], Changed(Definition(A.x1))[method x1 changed from ()Int to ()String flags: <method> <triedcooking>], Changed(Definition(A.x2))[method x2 changed from ()Int to ()String flags: <method> <triedcooking>]), object B -> List(Changed(Definition(B.x0))[method x0 changed from ()Int to ()String flags: <method>], Changed(Definition(B.x1))[method x1 changed from ()Int to ()String flags: <method>])) diff --git a/test/files/buildmanager/t2562/t2562.test b/test/files/buildmanager/t2562/t2562.test deleted file mode 100644 index 6f3bd03361..0000000000 --- a/test/files/buildmanager/t2562/t2562.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile A.scala B.scala ->>update A.scala=>A2.scala ->>compile A.scala diff --git a/test/files/buildmanager/t2649/A.scala b/test/files/buildmanager/t2649/A.scala deleted file mode 100644 index 86cc3f2c15..0000000000 --- a/test/files/buildmanager/t2649/A.scala +++ /dev/null @@ -1,3 +0,0 @@ -object A { - def x(zz: Int, yy: Int) = yy - zz -} diff --git a/test/files/buildmanager/t2649/B.scala b/test/files/buildmanager/t2649/B.scala deleted file mode 100644 index 26c89518cb..0000000000 --- a/test/files/buildmanager/t2649/B.scala +++ /dev/null @@ -1,4 +0,0 @@ -object B { - def main(args: Array[String]): Unit = - println( A.x(zz = 3, yy = 4) ) -} diff --git a/test/files/buildmanager/t2649/t2649.changes/A2.scala b/test/files/buildmanager/t2649/t2649.changes/A2.scala deleted file mode 100644 index 9a6309fca3..0000000000 --- a/test/files/buildmanager/t2649/t2649.changes/A2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object A { - def x(yy: Int, zz: Int) = yy - zz -} - diff --git a/test/files/buildmanager/t2649/t2649.check b/test/files/buildmanager/t2649/t2649.check deleted file mode 100644 index d0f41f32ec..0000000000 --- a/test/files/buildmanager/t2649/t2649.check +++ /dev/null @@ -1,9 +0,0 @@ -builder > A.scala B.scala -compiling Set(A.scala, B.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(object A -> List(Changed(Definition(A.x))[method x changed from (zz: Int, yy: Int)Int to (yy: Int, zz: Int)Int flags: <method> <triedcooking>])) -invalidate B.scala because it references changed definition [Changed(Definition(A.x))[method x changed from (zz: Int, yy: Int)Int to (yy: Int, zz: Int)Int flags: <method> <triedcooking>]] -compiling Set(B.scala) -Changes: Map(object B -> List()) diff --git a/test/files/buildmanager/t2649/t2649.test b/test/files/buildmanager/t2649/t2649.test deleted file mode 100644 index 6f3bd03361..0000000000 --- a/test/files/buildmanager/t2649/t2649.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile A.scala B.scala ->>update A.scala=>A2.scala ->>compile A.scala diff --git a/test/files/buildmanager/t2650_1/A.scala b/test/files/buildmanager/t2650_1/A.scala deleted file mode 100644 index 74714a3c47..0000000000 --- a/test/files/buildmanager/t2650_1/A.scala +++ /dev/null @@ -1,4 +0,0 @@ -trait A { - type S[_] -} - diff --git a/test/files/buildmanager/t2650_1/B.scala b/test/files/buildmanager/t2650_1/B.scala deleted file mode 100644 index 80f0e30259..0000000000 --- a/test/files/buildmanager/t2650_1/B.scala +++ /dev/null @@ -1,3 +0,0 @@ -trait B extends A { - type F = S[Int] -} diff --git a/test/files/buildmanager/t2650_1/t2650_1.changes/A2.scala b/test/files/buildmanager/t2650_1/t2650_1.changes/A2.scala deleted file mode 100644 index 2b8ead4ff1..0000000000 --- a/test/files/buildmanager/t2650_1/t2650_1.changes/A2.scala +++ /dev/null @@ -1,3 +0,0 @@ -trait A { - type S -} diff --git a/test/files/buildmanager/t2650_1/t2650_1.check b/test/files/buildmanager/t2650_1/t2650_1.check deleted file mode 100644 index f1e4b1b8bc..0000000000 --- a/test/files/buildmanager/t2650_1/t2650_1.check +++ /dev/null @@ -1,12 +0,0 @@ -builder > A.scala B.scala -compiling Set(A.scala, B.scala) -warning: there were 1 feature warnings; re-run with -feature for details -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(trait A -> List(Changed(Definition(A.S))[type S changed from A.this.S[_] to A.this.S flags: <deferred>])) -invalidate B.scala because inherited method changed [Changed(Definition(A.S))[type S changed from A.this.S[_] to A.this.S flags: <deferred>]] -compiling Set(B.scala) -B.scala:2: error: B.this.S does not take type parameters - type F = S[Int] - ^ diff --git a/test/files/buildmanager/t2650_1/t2650_1.test b/test/files/buildmanager/t2650_1/t2650_1.test deleted file mode 100644 index 6f3bd03361..0000000000 --- a/test/files/buildmanager/t2650_1/t2650_1.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile A.scala B.scala ->>update A.scala=>A2.scala ->>compile A.scala diff --git a/test/files/buildmanager/t2650_2/A.scala b/test/files/buildmanager/t2650_2/A.scala deleted file mode 100644 index bcea634485..0000000000 --- a/test/files/buildmanager/t2650_2/A.scala +++ /dev/null @@ -1,3 +0,0 @@ -trait A { - type S = Int -} diff --git a/test/files/buildmanager/t2650_2/B.scala b/test/files/buildmanager/t2650_2/B.scala deleted file mode 100644 index 22a3a9a48e..0000000000 --- a/test/files/buildmanager/t2650_2/B.scala +++ /dev/null @@ -1,4 +0,0 @@ -trait B extends A { - def x: S - def y: Int = x -} diff --git a/test/files/buildmanager/t2650_2/t2650_2.changes/A2.scala b/test/files/buildmanager/t2650_2/t2650_2.changes/A2.scala deleted file mode 100644 index 8274c1b62d..0000000000 --- a/test/files/buildmanager/t2650_2/t2650_2.changes/A2.scala +++ /dev/null @@ -1,4 +0,0 @@ -trait A { - type S = Long -} - diff --git a/test/files/buildmanager/t2650_2/t2650_2.check b/test/files/buildmanager/t2650_2/t2650_2.check deleted file mode 100644 index 53a0287dfc..0000000000 --- a/test/files/buildmanager/t2650_2/t2650_2.check +++ /dev/null @@ -1,14 +0,0 @@ -builder > A.scala B.scala -compiling Set(A.scala, B.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(trait A -> List(Changed(Definition(A.S))[type S changed from A.this.S to A.this.S flags: ])) -invalidate B.scala because inherited method changed [Changed(Definition(A.S))[type S changed from A.this.S to A.this.S flags: ]] -compiling Set(B.scala) -B.scala:3: error: type mismatch; - found : B.this.S - (which expands to) Long - required: Int - def y: Int = x - ^ diff --git a/test/files/buildmanager/t2650_2/t2650_2.test b/test/files/buildmanager/t2650_2/t2650_2.test deleted file mode 100644 index 6f3bd03361..0000000000 --- a/test/files/buildmanager/t2650_2/t2650_2.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile A.scala B.scala ->>update A.scala=>A2.scala ->>compile A.scala diff --git a/test/files/buildmanager/t2650_3/A.scala b/test/files/buildmanager/t2650_3/A.scala deleted file mode 100644 index cd13843eb9..0000000000 --- a/test/files/buildmanager/t2650_3/A.scala +++ /dev/null @@ -1,4 +0,0 @@ -trait A { - type T = Int - def x: T -} diff --git a/test/files/buildmanager/t2650_3/B.scala b/test/files/buildmanager/t2650_3/B.scala deleted file mode 100644 index 46a8cf270a..0000000000 --- a/test/files/buildmanager/t2650_3/B.scala +++ /dev/null @@ -1,3 +0,0 @@ -object B { - def x(a: A): Int = a.x -} diff --git a/test/files/buildmanager/t2650_3/t2650_3.changes/A2.scala b/test/files/buildmanager/t2650_3/t2650_3.changes/A2.scala deleted file mode 100644 index e5667b2539..0000000000 --- a/test/files/buildmanager/t2650_3/t2650_3.changes/A2.scala +++ /dev/null @@ -1,4 +0,0 @@ -trait A { - type T = Long - def x: T -} diff --git a/test/files/buildmanager/t2650_3/t2650_3.check b/test/files/buildmanager/t2650_3/t2650_3.check deleted file mode 100644 index 5c6326d59f..0000000000 --- a/test/files/buildmanager/t2650_3/t2650_3.check +++ /dev/null @@ -1,14 +0,0 @@ -builder > A.scala B.scala -compiling Set(A.scala, B.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(trait A -> List(Changed(Definition(A.T))[type T changed from A.this.T to A.this.T flags: ])) -invalidate B.scala because it references changed definition [Changed(Definition(A.T))[type T changed from A.this.T to A.this.T flags: ]] -compiling Set(B.scala) -B.scala:2: error: type mismatch; - found : a.T - (which expands to) Long - required: Int - def x(a: A): Int = a.x - ^ diff --git a/test/files/buildmanager/t2650_3/t2650_3.test b/test/files/buildmanager/t2650_3/t2650_3.test deleted file mode 100644 index 6f3bd03361..0000000000 --- a/test/files/buildmanager/t2650_3/t2650_3.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile A.scala B.scala ->>update A.scala=>A2.scala ->>compile A.scala diff --git a/test/files/buildmanager/t2650_4/A.scala b/test/files/buildmanager/t2650_4/A.scala deleted file mode 100644 index b9a519eb48..0000000000 --- a/test/files/buildmanager/t2650_4/A.scala +++ /dev/null @@ -1,5 +0,0 @@ -trait A { - type T = Int - type T2 = T - def x: T2 -} diff --git a/test/files/buildmanager/t2650_4/B.scala b/test/files/buildmanager/t2650_4/B.scala deleted file mode 100644 index 46a8cf270a..0000000000 --- a/test/files/buildmanager/t2650_4/B.scala +++ /dev/null @@ -1,3 +0,0 @@ -object B { - def x(a: A): Int = a.x -} diff --git a/test/files/buildmanager/t2650_4/t2650_4.changes/A2.scala b/test/files/buildmanager/t2650_4/t2650_4.changes/A2.scala deleted file mode 100644 index 0220e7b7bc..0000000000 --- a/test/files/buildmanager/t2650_4/t2650_4.changes/A2.scala +++ /dev/null @@ -1,5 +0,0 @@ -trait A { - type T = Long - type T2 = T - def x: T2 -} diff --git a/test/files/buildmanager/t2650_4/t2650_4.check b/test/files/buildmanager/t2650_4/t2650_4.check deleted file mode 100644 index a4aeaddfbb..0000000000 --- a/test/files/buildmanager/t2650_4/t2650_4.check +++ /dev/null @@ -1,14 +0,0 @@ -builder > A.scala B.scala -compiling Set(A.scala, B.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(trait A -> List(Changed(Definition(A.T))[type T changed from A.this.T to A.this.T flags: ])) -invalidate B.scala because it references changed definition [Changed(Definition(A.T))[type T changed from A.this.T to A.this.T flags: ]] -compiling Set(B.scala) -B.scala:2: error: type mismatch; - found : a.T2 - (which expands to) Long - required: Int - def x(a: A): Int = a.x - ^ diff --git a/test/files/buildmanager/t2650_4/t2650_4.test b/test/files/buildmanager/t2650_4/t2650_4.test deleted file mode 100644 index 6f3bd03361..0000000000 --- a/test/files/buildmanager/t2650_4/t2650_4.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile A.scala B.scala ->>update A.scala=>A2.scala ->>compile A.scala diff --git a/test/files/buildmanager/t2651_2/A.scala b/test/files/buildmanager/t2651_2/A.scala deleted file mode 100644 index d712f6febe..0000000000 --- a/test/files/buildmanager/t2651_2/A.scala +++ /dev/null @@ -1 +0,0 @@ -trait A[T] diff --git a/test/files/buildmanager/t2651_2/t2651_2.changes/A2.scala b/test/files/buildmanager/t2651_2/t2651_2.changes/A2.scala deleted file mode 100644 index 7fb573e077..0000000000 --- a/test/files/buildmanager/t2651_2/t2651_2.changes/A2.scala +++ /dev/null @@ -1 +0,0 @@ -trait A[S] diff --git a/test/files/buildmanager/t2651_2/t2651_2.check b/test/files/buildmanager/t2651_2/t2651_2.check deleted file mode 100644 index dd789b7565..0000000000 --- a/test/files/buildmanager/t2651_2/t2651_2.check +++ /dev/null @@ -1,6 +0,0 @@ -builder > A.scala -compiling Set(A.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(trait A -> List()) diff --git a/test/files/buildmanager/t2651_2/t2651_2.test b/test/files/buildmanager/t2651_2/t2651_2.test deleted file mode 100644 index d0614473ce..0000000000 --- a/test/files/buildmanager/t2651_2/t2651_2.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile A.scala ->>update A.scala=>A2.scala ->>compile A.scala diff --git a/test/files/buildmanager/t2651_3/A.scala b/test/files/buildmanager/t2651_3/A.scala deleted file mode 100644 index 14f9e4662f..0000000000 --- a/test/files/buildmanager/t2651_3/A.scala +++ /dev/null @@ -1,3 +0,0 @@ -trait A[T, S] { - def x: T -} diff --git a/test/files/buildmanager/t2651_3/t2651_3.changes/A2.scala b/test/files/buildmanager/t2651_3/t2651_3.changes/A2.scala deleted file mode 100644 index 51bf27d1fa..0000000000 --- a/test/files/buildmanager/t2651_3/t2651_3.changes/A2.scala +++ /dev/null @@ -1,3 +0,0 @@ -trait A[T, S] { - def x: S -} diff --git a/test/files/buildmanager/t2651_3/t2651_3.check b/test/files/buildmanager/t2651_3/t2651_3.check deleted file mode 100644 index 2a60e3d806..0000000000 --- a/test/files/buildmanager/t2651_3/t2651_3.check +++ /dev/null @@ -1,6 +0,0 @@ -builder > A.scala -compiling Set(A.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(trait A -> List(Changed(Definition(A.x))[method x changed from ()T to ()S flags: <method> <deferred>])) diff --git a/test/files/buildmanager/t2651_3/t2651_3.test b/test/files/buildmanager/t2651_3/t2651_3.test deleted file mode 100644 index d0614473ce..0000000000 --- a/test/files/buildmanager/t2651_3/t2651_3.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile A.scala ->>update A.scala=>A2.scala ->>compile A.scala diff --git a/test/files/buildmanager/t2651_4/A.scala b/test/files/buildmanager/t2651_4/A.scala deleted file mode 100644 index 63f2a1643e..0000000000 --- a/test/files/buildmanager/t2651_4/A.scala +++ /dev/null @@ -1,5 +0,0 @@ -trait A[T, S] { - def x: T - def y(a: T) - def z[B <: T] -} diff --git a/test/files/buildmanager/t2651_4/B.scala b/test/files/buildmanager/t2651_4/B.scala deleted file mode 100644 index b33dbde676..0000000000 --- a/test/files/buildmanager/t2651_4/B.scala +++ /dev/null @@ -1,3 +0,0 @@ -trait B extends A[Int, String] { - def x = 3 -} diff --git a/test/files/buildmanager/t2651_4/t2651_4.changes/A2.scala b/test/files/buildmanager/t2651_4/t2651_4.changes/A2.scala deleted file mode 100644 index f155129d13..0000000000 --- a/test/files/buildmanager/t2651_4/t2651_4.changes/A2.scala +++ /dev/null @@ -1,5 +0,0 @@ -trait A[S, T] { - def x: T - def y(a: T) - def z[B <: T] -} diff --git a/test/files/buildmanager/t2651_4/t2651_4.check b/test/files/buildmanager/t2651_4/t2651_4.check deleted file mode 100644 index 74e5d8f99b..0000000000 --- a/test/files/buildmanager/t2651_4/t2651_4.check +++ /dev/null @@ -1,13 +0,0 @@ -builder > A.scala B.scala -compiling Set(A.scala, B.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(trait A -> List(Changed(Definition(A.x))[method x changed from ()T to ()T flags: <method> <deferred> <triedcooking>], Changed(Definition(A.y))[method y changed from (a: T)Unit to (a: T)Unit flags: <method> <deferred>], Changed(Definition(A.z))[method z changed from [B <: T]()Unit to [B <: T]()Unit flags: <method> <deferred>])) -invalidate B.scala because inherited method changed [Changed(Definition(A.x))[method x changed from ()T to ()T flags: <method> <deferred> <triedcooking>]] -compiling Set(B.scala) -B.scala:2: error: type mismatch; - found : Int(3) - required: String - def x = 3 - ^ diff --git a/test/files/buildmanager/t2651_4/t2651_4.test b/test/files/buildmanager/t2651_4/t2651_4.test deleted file mode 100644 index 6f3bd03361..0000000000 --- a/test/files/buildmanager/t2651_4/t2651_4.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile A.scala B.scala ->>update A.scala=>A2.scala ->>compile A.scala diff --git a/test/files/buildmanager/t2653/A.scala b/test/files/buildmanager/t2653/A.scala deleted file mode 100644 index fb17a158c7..0000000000 --- a/test/files/buildmanager/t2653/A.scala +++ /dev/null @@ -1,2 +0,0 @@ -class A[+T] - diff --git a/test/files/buildmanager/t2653/B.scala b/test/files/buildmanager/t2653/B.scala deleted file mode 100644 index 8f55a88e05..0000000000 --- a/test/files/buildmanager/t2653/B.scala +++ /dev/null @@ -1,3 +0,0 @@ -object B { - val a: A[Any] = new A[Int] -} diff --git a/test/files/buildmanager/t2653/t2653.changes/A2.scala b/test/files/buildmanager/t2653/t2653.changes/A2.scala deleted file mode 100644 index 51d13cce6e..0000000000 --- a/test/files/buildmanager/t2653/t2653.changes/A2.scala +++ /dev/null @@ -1,2 +0,0 @@ -class A[T] - diff --git a/test/files/buildmanager/t2653/t2653.check b/test/files/buildmanager/t2653/t2653.check deleted file mode 100644 index 36781522af..0000000000 --- a/test/files/buildmanager/t2653/t2653.check +++ /dev/null @@ -1,15 +0,0 @@ -builder > A.scala B.scala -compiling Set(A.scala, B.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(class A -> List(Changed(Class(A))[ tparams: List((type T,type T))], Changed(Definition(A.<init>))[constructor A changed from ()A[T] to ()A[T] flags: <method> <triedcooking>])) -invalidate B.scala because it references changed class [Changed(Class(A))[ tparams: List((type T,type T))]] -compiling Set(B.scala) -B.scala:2: error: type mismatch; - found : A[Int] - required: A[Any] -Note: Int <: Any, but class A is invariant in type T. -You may wish to define T as +T instead. (SLS 4.5) - val a: A[Any] = new A[Int] - ^ diff --git a/test/files/buildmanager/t2653/t2653.test b/test/files/buildmanager/t2653/t2653.test deleted file mode 100644 index 6f3bd03361..0000000000 --- a/test/files/buildmanager/t2653/t2653.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile A.scala B.scala ->>update A.scala=>A2.scala ->>compile A.scala diff --git a/test/files/buildmanager/t2654/A.scala b/test/files/buildmanager/t2654/A.scala deleted file mode 100644 index 75f396d039..0000000000 --- a/test/files/buildmanager/t2654/A.scala +++ /dev/null @@ -1,2 +0,0 @@ -class A - diff --git a/test/files/buildmanager/t2654/B.scala b/test/files/buildmanager/t2654/B.scala deleted file mode 100644 index a18aec3dbe..0000000000 --- a/test/files/buildmanager/t2654/B.scala +++ /dev/null @@ -1 +0,0 @@ -class B extends A diff --git a/test/files/buildmanager/t2654/t2654.changes/A2.scala b/test/files/buildmanager/t2654/t2654.changes/A2.scala deleted file mode 100644 index c302edbd85..0000000000 --- a/test/files/buildmanager/t2654/t2654.changes/A2.scala +++ /dev/null @@ -1,4 +0,0 @@ -class A { - private def x = 5 -} - diff --git a/test/files/buildmanager/t2654/t2654.check b/test/files/buildmanager/t2654/t2654.check deleted file mode 100644 index 68f6e8efc0..0000000000 --- a/test/files/buildmanager/t2654/t2654.check +++ /dev/null @@ -1,6 +0,0 @@ -builder > A.scala B.scala -compiling Set(A.scala, B.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(class A -> List()) diff --git a/test/files/buildmanager/t2654/t2654.test b/test/files/buildmanager/t2654/t2654.test deleted file mode 100644 index 6f3bd03361..0000000000 --- a/test/files/buildmanager/t2654/t2654.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile A.scala B.scala ->>update A.scala=>A2.scala ->>compile A.scala diff --git a/test/files/buildmanager/t2655/A.scala b/test/files/buildmanager/t2655/A.scala deleted file mode 100644 index b2c54ac47d..0000000000 --- a/test/files/buildmanager/t2655/A.scala +++ /dev/null @@ -1,4 +0,0 @@ -object A { - def x(i: => String) = () -} - diff --git a/test/files/buildmanager/t2655/B.scala b/test/files/buildmanager/t2655/B.scala deleted file mode 100644 index 6c1918c0fb..0000000000 --- a/test/files/buildmanager/t2655/B.scala +++ /dev/null @@ -1,3 +0,0 @@ -object B { - val x = A.x("3") -} diff --git a/test/files/buildmanager/t2655/t2655.changes/A2.scala b/test/files/buildmanager/t2655/t2655.changes/A2.scala deleted file mode 100644 index 0d6a7c69bb..0000000000 --- a/test/files/buildmanager/t2655/t2655.changes/A2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object A { - def x(i: Function0[String]) = () -} - diff --git a/test/files/buildmanager/t2655/t2655.check b/test/files/buildmanager/t2655/t2655.check deleted file mode 100644 index 41ce65a2f5..0000000000 --- a/test/files/buildmanager/t2655/t2655.check +++ /dev/null @@ -1,13 +0,0 @@ -builder > A.scala B.scala -compiling Set(A.scala, B.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(object A -> List(Changed(Definition(A.x))[method x changed from (i: Function0)Unit to (i: Function0)Unit flags: <method> <triedcooking>])) -invalidate B.scala because it references changed definition [Changed(Definition(A.x))[method x changed from (i: Function0)Unit to (i: Function0)Unit flags: <method> <triedcooking>]] -compiling Set(B.scala) -B.scala:2: error: type mismatch; - found : String("3") - required: () => String - val x = A.x("3") - ^ diff --git a/test/files/buildmanager/t2655/t2655.test b/test/files/buildmanager/t2655/t2655.test deleted file mode 100644 index 6f3bd03361..0000000000 --- a/test/files/buildmanager/t2655/t2655.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile A.scala B.scala ->>update A.scala=>A2.scala ->>compile A.scala diff --git a/test/files/buildmanager/t2657/A.scala b/test/files/buildmanager/t2657/A.scala deleted file mode 100644 index 2a6c62d29c..0000000000 --- a/test/files/buildmanager/t2657/A.scala +++ /dev/null @@ -1,3 +0,0 @@ -class A { - implicit def y(i: Int): String = i.toString -} diff --git a/test/files/buildmanager/t2657/B.scala b/test/files/buildmanager/t2657/B.scala deleted file mode 100644 index 77869890db..0000000000 --- a/test/files/buildmanager/t2657/B.scala +++ /dev/null @@ -1,4 +0,0 @@ -object B extends A { - val x: String = 3 -} - diff --git a/test/files/buildmanager/t2657/t2657.changes/A2.scala b/test/files/buildmanager/t2657/t2657.changes/A2.scala deleted file mode 100644 index 7dc99d425e..0000000000 --- a/test/files/buildmanager/t2657/t2657.changes/A2.scala +++ /dev/null @@ -1,3 +0,0 @@ -class A { - def y(i: Int): String = i.toString -} diff --git a/test/files/buildmanager/t2657/t2657.check b/test/files/buildmanager/t2657/t2657.check deleted file mode 100644 index 0d6709e58b..0000000000 --- a/test/files/buildmanager/t2657/t2657.check +++ /dev/null @@ -1,14 +0,0 @@ -builder > A.scala B.scala -compiling Set(A.scala, B.scala) -warning: there were 1 feature warnings; re-run with -feature for details -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(class A -> List(Changed(Definition(A.y))[method y changed from (i: Int)String to (i: Int)String flags: <method> implicit <triedcooking>])) -invalidate B.scala because inherited method changed [Changed(Definition(A.y))[method y changed from (i: Int)String to (i: Int)String flags: <method> implicit <triedcooking>]] -compiling Set(B.scala) -B.scala:2: error: type mismatch; - found : Int(3) - required: String - val x: String = 3 - ^ diff --git a/test/files/buildmanager/t2657/t2657.test b/test/files/buildmanager/t2657/t2657.test deleted file mode 100644 index 6f3bd03361..0000000000 --- a/test/files/buildmanager/t2657/t2657.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile A.scala B.scala ->>update A.scala=>A2.scala ->>compile A.scala diff --git a/test/files/buildmanager/t2789/A.scala b/test/files/buildmanager/t2789/A.scala deleted file mode 100644 index 08d5bc840c..0000000000 --- a/test/files/buildmanager/t2789/A.scala +++ /dev/null @@ -1,5 +0,0 @@ -class A { - implicit def e: E = new E - def x(i: Int)(implicit y: E): String = "" -} -class E diff --git a/test/files/buildmanager/t2789/B.scala b/test/files/buildmanager/t2789/B.scala deleted file mode 100644 index dcefbeec1b..0000000000 --- a/test/files/buildmanager/t2789/B.scala +++ /dev/null @@ -1,3 +0,0 @@ -object B extends A { - val y = x(3) -} diff --git a/test/files/buildmanager/t2789/t2789.changes/A2.scala b/test/files/buildmanager/t2789/t2789.changes/A2.scala deleted file mode 100644 index 4ba3814e71..0000000000 --- a/test/files/buildmanager/t2789/t2789.changes/A2.scala +++ /dev/null @@ -1,5 +0,0 @@ -class A { - def e: E = new E - def x(i: Int)(implicit y: E): String = "" -} -class E diff --git a/test/files/buildmanager/t2789/t2789.check b/test/files/buildmanager/t2789/t2789.check deleted file mode 100644 index 066561ac44..0000000000 --- a/test/files/buildmanager/t2789/t2789.check +++ /dev/null @@ -1,11 +0,0 @@ -builder > A.scala B.scala -compiling Set(A.scala, B.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(class A -> List(Changed(Definition(A.e))[method e changed from ()E to ()E flags: <method> implicit <triedcooking>]), class E -> List()) -invalidate B.scala because inherited method changed [Changed(Definition(A.e))[method e changed from ()E to ()E flags: <method> implicit <triedcooking>]] -compiling Set(B.scala) -B.scala:2: error: could not find implicit value for parameter y: E - val y = x(3) - ^ diff --git a/test/files/buildmanager/t2789/t2789.test b/test/files/buildmanager/t2789/t2789.test deleted file mode 100644 index 6f3bd03361..0000000000 --- a/test/files/buildmanager/t2789/t2789.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile A.scala B.scala ->>update A.scala=>A2.scala ->>compile A.scala diff --git a/test/files/buildmanager/t2790/A.scala b/test/files/buildmanager/t2790/A.scala deleted file mode 100644 index 6e9c1a90db..0000000000 --- a/test/files/buildmanager/t2790/A.scala +++ /dev/null @@ -1,5 +0,0 @@ -object A { - def x(f: String, g: Int): Int = g - def x(f: Int, g: Int = 3): Int = g -} - diff --git a/test/files/buildmanager/t2790/B.scala b/test/files/buildmanager/t2790/B.scala deleted file mode 100644 index 441055ca12..0000000000 --- a/test/files/buildmanager/t2790/B.scala +++ /dev/null @@ -1,4 +0,0 @@ -object B { - val y = A.x(5) -} - diff --git a/test/files/buildmanager/t2790/t2790.changes/A2.scala b/test/files/buildmanager/t2790/t2790.changes/A2.scala deleted file mode 100644 index 704ef4e96e..0000000000 --- a/test/files/buildmanager/t2790/t2790.changes/A2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object A { - def x(f: String, g: Int = 3): Int = g - def x(f: Int, g: Int): Int = g -} diff --git a/test/files/buildmanager/t2790/t2790.check b/test/files/buildmanager/t2790/t2790.check deleted file mode 100644 index 13d61dac42..0000000000 --- a/test/files/buildmanager/t2790/t2790.check +++ /dev/null @@ -1,13 +0,0 @@ -builder > A.scala B.scala -compiling Set(A.scala, B.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(object A -> List(Added(Definition(A.x)), Changed(Definition(A.x))[value x changed from (f: String, g: Int)Int to (f: String, g: Int)Int <and> (f: Int, g: Int)Int flags: <method>])) -invalidate B.scala because it references changed definition [Changed(Definition(A.x))[value x changed from (f: String, g: Int)Int to (f: String, g: Int)Int <and> (f: Int, g: Int)Int flags: <method>]] -compiling Set(B.scala) -B.scala:2: error: type mismatch; - found : Int(5) - required: String - val y = A.x(5) - ^ diff --git a/test/files/buildmanager/t2790/t2790.test b/test/files/buildmanager/t2790/t2790.test deleted file mode 100644 index 6f3bd03361..0000000000 --- a/test/files/buildmanager/t2790/t2790.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile A.scala B.scala ->>update A.scala=>A2.scala ->>compile A.scala diff --git a/test/files/buildmanager/t2792/A1.scala b/test/files/buildmanager/t2792/A1.scala deleted file mode 100644 index 96dc0ef933..0000000000 --- a/test/files/buildmanager/t2792/A1.scala +++ /dev/null @@ -1,3 +0,0 @@ -object A { - val x = new C -} diff --git a/test/files/buildmanager/t2792/A2.scala b/test/files/buildmanager/t2792/A2.scala deleted file mode 100644 index e55e681c76..0000000000 --- a/test/files/buildmanager/t2792/A2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object B { - import A.x.y - val z = y -} diff --git a/test/files/buildmanager/t2792/A3.scala b/test/files/buildmanager/t2792/A3.scala deleted file mode 100644 index cd083cdb34..0000000000 --- a/test/files/buildmanager/t2792/A3.scala +++ /dev/null @@ -1,3 +0,0 @@ -class C { - val y = 4 -} diff --git a/test/files/buildmanager/t2792/t2792.changes/A1_1.scala b/test/files/buildmanager/t2792/t2792.changes/A1_1.scala deleted file mode 100644 index 00ee05f273..0000000000 --- a/test/files/buildmanager/t2792/t2792.changes/A1_1.scala +++ /dev/null @@ -1,3 +0,0 @@ -object A { - var x = new C -} diff --git a/test/files/buildmanager/t2792/t2792.check b/test/files/buildmanager/t2792/t2792.check deleted file mode 100644 index 00a2b83469..0000000000 --- a/test/files/buildmanager/t2792/t2792.check +++ /dev/null @@ -1,14 +0,0 @@ -builder > A1.scala A2.scala A3.scala -compiling Set(A1.scala, A2.scala, A3.scala) -Changes: Map() -builder > A1.scala -compiling Set(A1.scala) -Changes: Map(object A -> List(Added(Definition(A.x_$eq)), Changed(Definition(A.x))[value x changed to variable x])) -invalidate A2.scala because it references changed definition [Changed(Definition(A.x))[value x changed to variable x]] -compiling Set(A2.scala) -A2.scala:2: error: stable identifier required, but A.x found. - import A.x.y - ^ -A2.scala:3: error: not found: value y - val z = y - ^ diff --git a/test/files/buildmanager/t2792/t2792.test b/test/files/buildmanager/t2792/t2792.test deleted file mode 100644 index f199950bba..0000000000 --- a/test/files/buildmanager/t2792/t2792.test +++ /dev/null @@ -1,3 +0,0 @@ ->>compile A1.scala A2.scala A3.scala ->>update A1.scala=>A1_1.scala ->>compile A1.scala diff --git a/test/files/buildmanager/t3045/A.java b/test/files/buildmanager/t3045/A.java deleted file mode 100644 index d1acb00cd6..0000000000 --- a/test/files/buildmanager/t3045/A.java +++ /dev/null @@ -1,7 +0,0 @@ -public interface A { - public class C implements A {} -} - -class B { - static class C {} -} diff --git a/test/files/buildmanager/t3045/t3045.check b/test/files/buildmanager/t3045/t3045.check deleted file mode 100644 index 5e4e71e045..0000000000 --- a/test/files/buildmanager/t3045/t3045.check +++ /dev/null @@ -1,3 +0,0 @@ -builder > A.java -compiling Set(A.java) -Changes: Map() diff --git a/test/files/buildmanager/t3045/t3045.test b/test/files/buildmanager/t3045/t3045.test deleted file mode 100644 index 6cf7e35543..0000000000 --- a/test/files/buildmanager/t3045/t3045.test +++ /dev/null @@ -1 +0,0 @@ ->>compile A.java diff --git a/test/files/buildmanager/t3054/bar/Bar.java b/test/files/buildmanager/t3054/bar/Bar.java deleted file mode 100644 index e1b056d4e5..0000000000 --- a/test/files/buildmanager/t3054/bar/Bar.java +++ /dev/null @@ -1,7 +0,0 @@ -package bar; -import foo.Foo$; - - -public class Bar { - void bar() { Foo$.MODULE$.foo(); } -} diff --git a/test/files/buildmanager/t3054/foo/Foo.scala b/test/files/buildmanager/t3054/foo/Foo.scala deleted file mode 100644 index c0fcd97390..0000000000 --- a/test/files/buildmanager/t3054/foo/Foo.scala +++ /dev/null @@ -1,5 +0,0 @@ -package foo - -class Foo { - def foo() = println("foo") -} diff --git a/test/files/buildmanager/t3054/t3054.check b/test/files/buildmanager/t3054/t3054.check deleted file mode 100644 index 97cca8862e..0000000000 --- a/test/files/buildmanager/t3054/t3054.check +++ /dev/null @@ -1,3 +0,0 @@ -builder > bar/Bar.java foo/Foo.scala -compiling Set(bar/Bar.java, foo/Foo.scala) -Changes: Map() diff --git a/test/files/buildmanager/t3054/t3054.test b/test/files/buildmanager/t3054/t3054.test deleted file mode 100644 index 903df24b13..0000000000 --- a/test/files/buildmanager/t3054/t3054.test +++ /dev/null @@ -1 +0,0 @@ ->>compile bar/Bar.java foo/Foo.scala diff --git a/test/files/buildmanager/t3059/A.scala b/test/files/buildmanager/t3059/A.scala deleted file mode 100644 index 0dd25f6647..0000000000 --- a/test/files/buildmanager/t3059/A.scala +++ /dev/null @@ -1,4 +0,0 @@ -class A extends B { - private def getBar = List(1,2,3) - lazy val bar: List[Int] = getBar -} diff --git a/test/files/buildmanager/t3059/B.scala b/test/files/buildmanager/t3059/B.scala deleted file mode 100644 index 46596870ac..0000000000 --- a/test/files/buildmanager/t3059/B.scala +++ /dev/null @@ -1,4 +0,0 @@ -abstract class B { - private def getFoo = 12 - lazy val foo: Int = getFoo -} diff --git a/test/files/buildmanager/t3059/t3059.check b/test/files/buildmanager/t3059/t3059.check deleted file mode 100644 index 4a8076aae1..0000000000 --- a/test/files/buildmanager/t3059/t3059.check +++ /dev/null @@ -1,6 +0,0 @@ -builder > A.scala B.scala -compiling Set(A.scala, B.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(class A -> List())
\ No newline at end of file diff --git a/test/files/buildmanager/t3059/t3059.test b/test/files/buildmanager/t3059/t3059.test deleted file mode 100644 index 6f3749dc4b..0000000000 --- a/test/files/buildmanager/t3059/t3059.test +++ /dev/null @@ -1,2 +0,0 @@ ->>compile A.scala B.scala ->>compile A.scala
\ No newline at end of file diff --git a/test/files/buildmanager/t3133/A.java b/test/files/buildmanager/t3133/A.java deleted file mode 100644 index c4e7f3af0e..0000000000 --- a/test/files/buildmanager/t3133/A.java +++ /dev/null @@ -1,7 +0,0 @@ -public class A { - class Foo {} - - public A(Foo a) {} - - private void bar(Foo z) {} -} diff --git a/test/files/buildmanager/t3133/t3133.check b/test/files/buildmanager/t3133/t3133.check deleted file mode 100644 index 5e4e71e045..0000000000 --- a/test/files/buildmanager/t3133/t3133.check +++ /dev/null @@ -1,3 +0,0 @@ -builder > A.java -compiling Set(A.java) -Changes: Map() diff --git a/test/files/buildmanager/t3133/t3133.test b/test/files/buildmanager/t3133/t3133.test deleted file mode 100644 index 6cf7e35543..0000000000 --- a/test/files/buildmanager/t3133/t3133.test +++ /dev/null @@ -1 +0,0 @@ ->>compile A.java diff --git a/test/files/buildmanager/t3140/A.scala b/test/files/buildmanager/t3140/A.scala deleted file mode 100644 index f7768044d1..0000000000 --- a/test/files/buildmanager/t3140/A.scala +++ /dev/null @@ -1,8 +0,0 @@ -class As { - trait A { - def foo(parents: String): A = { - (() => parents) - null - } - } -} diff --git a/test/files/buildmanager/t3140/t3140.check b/test/files/buildmanager/t3140/t3140.check deleted file mode 100644 index 008d5a9618..0000000000 --- a/test/files/buildmanager/t3140/t3140.check +++ /dev/null @@ -1,6 +0,0 @@ -builder > A.scala -compiling Set(A.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(class As -> List(), object As$A$class -> List(), trait As$A -> List()) diff --git a/test/files/buildmanager/t3140/t3140.test b/test/files/buildmanager/t3140/t3140.test deleted file mode 100644 index 392e0d365f..0000000000 --- a/test/files/buildmanager/t3140/t3140.test +++ /dev/null @@ -1,2 +0,0 @@ ->>compile A.scala ->>compile A.scala diff --git a/test/files/buildmanager/t4215/A.scala b/test/files/buildmanager/t4215/A.scala deleted file mode 100644 index 9db40b0fee..0000000000 --- a/test/files/buildmanager/t4215/A.scala +++ /dev/null @@ -1,5 +0,0 @@ -class A { - def B() { - object C - } -} diff --git a/test/files/buildmanager/t4215/t4215.check b/test/files/buildmanager/t4215/t4215.check deleted file mode 100644 index d9ec9a743a..0000000000 --- a/test/files/buildmanager/t4215/t4215.check +++ /dev/null @@ -1,6 +0,0 @@ -builder > A.scala -compiling Set(A.scala) -Changes: Map() -builder > A.scala -compiling Set(A.scala) -Changes: Map(class A -> List(), object A$C$2 -> List()) diff --git a/test/files/buildmanager/t4215/t4215.test b/test/files/buildmanager/t4215/t4215.test deleted file mode 100644 index 392e0d365f..0000000000 --- a/test/files/buildmanager/t4215/t4215.test +++ /dev/null @@ -1,2 +0,0 @@ ->>compile A.scala ->>compile A.scala diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-a.check b/test/files/neg/macro-override-macro-overrides-abstract-method-a.check index 895e0dca50..8c8f039225 100644 --- a/test/files/neg/macro-override-macro-overrides-abstract-method-a.check +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-a.check @@ -1,5 +1,5 @@ Impls_Macros_1.scala:12: error: overriding method foo in trait Foo of type (x: Int)Int; - macro method foo cannot override an abstract method + macro method foo cannot be used here - term macros cannot override abstract methods def foo(x: Int) = macro Impls.impl ^ one error found diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-b.check b/test/files/neg/macro-override-macro-overrides-abstract-method-b.check index 895e0dca50..8c8f039225 100644 --- a/test/files/neg/macro-override-macro-overrides-abstract-method-b.check +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-b.check @@ -1,5 +1,5 @@ Impls_Macros_1.scala:12: error: overriding method foo in trait Foo of type (x: Int)Int; - macro method foo cannot override an abstract method + macro method foo cannot be used here - term macros cannot override abstract methods def foo(x: Int) = macro Impls.impl ^ one error found diff --git a/test/files/neg/macro-override-method-overrides-macro.check b/test/files/neg/macro-override-method-overrides-macro.check index 66dc11be96..e8cba5d029 100644 --- a/test/files/neg/macro-override-method-overrides-macro.check +++ b/test/files/neg/macro-override-method-overrides-macro.check @@ -1,5 +1,5 @@ Macros_Test_2.scala:8: error: overriding macro method foo in class B of type (x: String)Unit; - method foo cannot override a macro + method foo cannot be used here - only term macros can override term macros override def foo(x: String) = println("fooDString") ^ one error found diff --git a/test/files/neg/t5189_inferred.check b/test/files/neg/t5189_inferred.check new file mode 100644 index 0000000000..9cc5dcc242 --- /dev/null +++ b/test/files/neg/t5189_inferred.check @@ -0,0 +1,6 @@ +t5189_inferred.scala:7: error: type mismatch; + found : scala.collection.immutable.Nil.type + required: ?A1 where type ?A1 + f(Invariant(arr): Covariant[Any])(0) = Nil + ^ +one error found diff --git a/test/files/neg/t5189_inferred.scala b/test/files/neg/t5189_inferred.scala new file mode 100644 index 0000000000..e4e8765445 --- /dev/null +++ b/test/files/neg/t5189_inferred.scala @@ -0,0 +1,8 @@ +trait Covariant[+A] +case class Invariant[A](xs: Array[A]) extends Covariant[A] + +class Test { + val arr = Array("abc") + def f[A](v: Covariant[A]) /*inferred!*/ = v match { case Invariant(xs) => xs } + f(Invariant(arr): Covariant[Any])(0) = Nil +}
\ No newline at end of file diff --git a/test/files/neg/t5353.check b/test/files/neg/t5353.check deleted file mode 100644 index 75e2435600..0000000000 --- a/test/files/neg/t5353.check +++ /dev/null @@ -1,4 +0,0 @@ -t5353.scala:2: error: this type parameter must be specified - def f(x: Boolean) = if (x) Array("abc") else Array() - ^ -one error found diff --git a/test/files/neg/t5353.scala b/test/files/neg/t5353.scala deleted file mode 100644 index 1ee869aac1..0000000000 --- a/test/files/neg/t5353.scala +++ /dev/null @@ -1,3 +0,0 @@ -class A { - def f(x: Boolean) = if (x) Array("abc") else Array() -} diff --git a/test/files/neg/t6375.check b/test/files/neg/t6375.check new file mode 100644 index 0000000000..89d7d8060f --- /dev/null +++ b/test/files/neg/t6375.check @@ -0,0 +1,27 @@ +t6375.scala:6: warning: no valid targets for annotation on value x1 - it is discarded unused. You may specify targets with meta-annotations, e.g. @(Bippy @getter) + @Bippy val x1: Int // warn + ^ +t6375.scala:7: warning: no valid targets for annotation on value x2 - it is discarded unused. You may specify targets with meta-annotations, e.g. @(Bippy @scala.annotation.meta.field @getter) + @(Bippy @field) val x2: Int // warn + ^ +t6375.scala:9: warning: no valid targets for annotation on value x4 - it is discarded unused. You may specify targets with meta-annotations, e.g. @(Bippy @scala.annotation.meta.setter @getter) + @(Bippy @setter) val x4: Int // warn + ^ +t6375.scala:10: warning: no valid targets for annotation on value x5 - it is discarded unused. You may specify targets with meta-annotations, e.g. @(Bippy @scala.annotation.meta.param @getter) + @(Bippy @param) val x5: Int // warn + ^ +t6375.scala:20: warning: no valid targets for annotation on value q1 - it is discarded unused. You may specify targets with meta-annotations, e.g. @(Bippy @scala.annotation.meta.getter @field) + @(Bippy @getter) private[this] val q1: Int = 1 // warn + ^ +t6375.scala:40: warning: no valid targets for annotation on value p2 - it is discarded unused. You may specify targets with meta-annotations, e.g. @(Bippy @scala.annotation.meta.getter @param) + @(Bippy @getter) p2: Int, // warn + ^ +t6375.scala:41: warning: no valid targets for annotation on value p3 - it is discarded unused. You may specify targets with meta-annotations, e.g. @(Bippy @scala.annotation.meta.setter @param) + @(Bippy @setter) p3: Int, // warn + ^ +t6375.scala:42: warning: no valid targets for annotation on value p4 - it is discarded unused. You may specify targets with meta-annotations, e.g. @(Bippy @scala.annotation.meta.field @param) + @(Bippy @field) p4: Int // warn + ^ +error: No warnings can be incurred under -Xfatal-warnings. +8 warnings found +one error found diff --git a/test/files/neg/t6375.flags b/test/files/neg/t6375.flags new file mode 100644 index 0000000000..85d8eb2ba2 --- /dev/null +++ b/test/files/neg/t6375.flags @@ -0,0 +1 @@ +-Xfatal-warnings diff --git a/test/files/neg/t6375.scala b/test/files/neg/t6375.scala new file mode 100644 index 0000000000..21634df688 --- /dev/null +++ b/test/files/neg/t6375.scala @@ -0,0 +1,67 @@ +import scala.annotation.meta._ + +class Bippy extends scala.annotation.StaticAnnotation + +abstract class Foo { + @Bippy val x1: Int // warn + @(Bippy @field) val x2: Int // warn + @(Bippy @getter) val x3: Int // no warn + @(Bippy @setter) val x4: Int // warn + @(Bippy @param) val x5: Int // warn +} + +object Bar extends Foo { + val x1 = 1 + val x2 = 2 + val x3 = 3 + val x4 = 4 + val x5 = 5 + + @(Bippy @getter) private[this] val q1: Int = 1 // warn + @(Bippy @getter) private val q2: Int = 1 // no warn + + def f1(@(Bippy @param) x: Int): Int = 0 // no warn + def f2(@(Bippy @getter) x: Int): Int = 0 // warn - todo + def f3(@(Bippy @setter) x: Int): Int = 0 // warn - todo + def f4(@(Bippy @field) x: Int): Int = 0 // warn - todo + def f5(@Bippy x: Int): Int = 0 // no warn + + @(Bippy @companionClass) def g1(x: Int): Int = 0 // warn - todo + @(Bippy @companionObject) def g2(x: Int): Int = 0 // warn - todo + @(Bippy @companionMethod) def g3(x: Int): Int = 0 // no warn + @Bippy def g4(x: Int): Int = 0 // no warn + + @(Bippy @companionObject @companionMethod) def g5(x: Int): Int = 0 // no warn +} + +class Dingo( + @Bippy p0: Int, // no warn + @(Bippy @param) p1: Int, // no warn + @(Bippy @getter) p2: Int, // warn + @(Bippy @setter) p3: Int, // warn + @(Bippy @field) p4: Int // warn +) + +class ValDingo( + @Bippy val p0: Int, // no warn + @(Bippy @param) val p1: Int, // no warn + @(Bippy @getter) val p2: Int, // no warn + @(Bippy @setter) val p3: Int, // warn - todo + @(Bippy @field) val p4: Int // no warn +) + +class VarDingo( + @Bippy var p0: Int, // no warn + @(Bippy @param) var p1: Int, // no warn + @(Bippy @getter) var p2: Int, // no warn + @(Bippy @setter) var p3: Int, // no warn + @(Bippy @field) var p4: Int // no warn +) + +case class CaseDingo( + @Bippy p0: Int, // no warn + @(Bippy @param) p1: Int, // no warn + @(Bippy @getter) p2: Int, // no warn + @(Bippy @setter) p3: Int, // warn - todo + @(Bippy @field) p4: Int // no warn +) diff --git a/test/files/pos/CustomGlobal.scala b/test/files/pos/CustomGlobal.scala index 30bf227950..a5668bd7c0 100644 --- a/test/files/pos/CustomGlobal.scala +++ b/test/files/pos/CustomGlobal.scala @@ -22,7 +22,7 @@ class CustomGlobal(currentSettings: Settings, reporter: Reporter) extends Global override def newTyper(context: Context): Typer = new CustomTyper(context) class CustomTyper(context : Context) extends Typer(context) { - override def typed(tree: Tree, mode: Int, pt: Type): Tree = { + override def typed(tree: Tree, mode: Mode, pt: Type): Tree = { if (tree.summaryString contains "Bippy") println("I'm typing a Bippy! It's a " + tree.shortClass + ".") diff --git a/test/files/neg/t5692a.check b/test/files/pos/t5692a.check index 7fbfb5dba7..7fbfb5dba7 100644 --- a/test/files/neg/t5692a.check +++ b/test/files/pos/t5692a.check diff --git a/test/files/neg/t5692a.flags b/test/files/pos/t5692a.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/neg/t5692a.flags +++ b/test/files/pos/t5692a.flags diff --git a/test/files/neg/t5692a/Macros_1.scala b/test/files/pos/t5692a/Macros_1.scala index 06b5a3de36..06b5a3de36 100644 --- a/test/files/neg/t5692a/Macros_1.scala +++ b/test/files/pos/t5692a/Macros_1.scala diff --git a/test/files/neg/t5692a/Test_2.scala b/test/files/pos/t5692a/Test_2.scala index 08d510cc6f..08d510cc6f 100644 --- a/test/files/neg/t5692a/Test_2.scala +++ b/test/files/pos/t5692a/Test_2.scala diff --git a/test/files/neg/t5692b.check b/test/files/pos/t5692b.check index 16796826b4..16796826b4 100644 --- a/test/files/neg/t5692b.check +++ b/test/files/pos/t5692b.check diff --git a/test/files/neg/t5692b.flags b/test/files/pos/t5692b.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/neg/t5692b.flags +++ b/test/files/pos/t5692b.flags diff --git a/test/files/neg/t5692b/Macros_1.scala b/test/files/pos/t5692b/Macros_1.scala index b28d19f903..b28d19f903 100644 --- a/test/files/neg/t5692b/Macros_1.scala +++ b/test/files/pos/t5692b/Macros_1.scala diff --git a/test/files/neg/t5692b/Test_2.scala b/test/files/pos/t5692b/Test_2.scala index 08d510cc6f..08d510cc6f 100644 --- a/test/files/neg/t5692b/Test_2.scala +++ b/test/files/pos/t5692b/Test_2.scala diff --git a/test/files/pos/t6966.scala b/test/files/pos/t6966.scala new file mode 100644 index 0000000000..23adc6d0d2 --- /dev/null +++ b/test/files/pos/t6966.scala @@ -0,0 +1,17 @@ +import Ordering.{Byte, comparatorToOrdering} +trait Format[T] +trait InputCache[T] +object CacheIvy { + implicit def basicInputCache[I](implicit fmt: Format[I], eqv: Equiv[I]): InputCache[I] = null + implicit def arrEquiv[T](implicit t: Equiv[T]): Equiv[Array[T]] = null + implicit def hNilCache: InputCache[HNil] = null + implicit def ByteArrayFormat: Format[Array[Byte]] = null + type :+:[H, T <: HList] = HCons[H,T] + implicit def hConsCache[H, T <: HList](implicit head: InputCache[H], tail: InputCache[T]): InputCache[H :+: T] = null + hConsCache[Array[Byte], HNil] +} + +sealed trait HList +sealed trait HNil extends HList +object HNil extends HNil +final class HCons[H, T <: HList](head : H, tail : T) extends HList
\ No newline at end of file diff --git a/test/files/run/macro-expand-unapply-a.check b/test/files/run/macro-expand-unapply-a.check new file mode 100644 index 0000000000..7c2976e51e --- /dev/null +++ b/test/files/run/macro-expand-unapply-a.check @@ -0,0 +1,2 @@ +(1,2) +(1,2,3) diff --git a/test/files/run/macro-expand-unapply-a.flags b/test/files/run/macro-expand-unapply-a.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-expand-unapply-a.flags @@ -0,0 +1 @@ +-language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-expand-unapply-a/Impls_Macros_1.scala b/test/files/run/macro-expand-unapply-a/Impls_Macros_1.scala new file mode 100644 index 0000000000..61d6345f16 --- /dev/null +++ b/test/files/run/macro-expand-unapply-a/Impls_Macros_1.scala @@ -0,0 +1,15 @@ +import scala.reflect.macros.Context + +object Helper { + def unapplySeq[T](x: List[T]): Option[Seq[T]] = List.unapplySeq[T](x) +} + +object Macros { + def impl[T: c.WeakTypeTag](c: Context)(x: c.Expr[List[T]]) = { + c.universe.reify(Helper.unapplySeq(x.splice)) + } + + object UnapplyMacro { + def unapplySeq[T](x: List[T]): Option[Seq[T]] = macro impl[T] + } +}
\ No newline at end of file diff --git a/test/files/run/macro-expand-unapply-a/Test_2.scala b/test/files/run/macro-expand-unapply-a/Test_2.scala new file mode 100644 index 0000000000..6169d86b19 --- /dev/null +++ b/test/files/run/macro-expand-unapply-a/Test_2.scala @@ -0,0 +1,6 @@ +import Macros._ + +object Test extends App { + List(1, 2) match { case UnapplyMacro(x, y) => println((x, y)) } + List(1, 2, 3) match { case UnapplyMacro(x, y, z) => println((x, y, z)) } +}
\ No newline at end of file diff --git a/test/files/run/macro-expand-unapply-b.check b/test/files/run/macro-expand-unapply-b.check new file mode 100644 index 0000000000..5272f0d00a --- /dev/null +++ b/test/files/run/macro-expand-unapply-b.check @@ -0,0 +1,2 @@ +(1,List(2)) +List(1) diff --git a/test/files/run/macro-expand-unapply-b.flags b/test/files/run/macro-expand-unapply-b.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-expand-unapply-b.flags @@ -0,0 +1 @@ +-language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-expand-unapply-b/Impls_Macros_1.scala b/test/files/run/macro-expand-unapply-b/Impls_Macros_1.scala new file mode 100644 index 0000000000..d0300bdf7e --- /dev/null +++ b/test/files/run/macro-expand-unapply-b/Impls_Macros_1.scala @@ -0,0 +1,37 @@ +import language.experimental.macros +import scala.reflect.macros.Context + +object Macros { + implicit class ContextExtensions(c: StringContext) { + object q { + def unapply(x: Any): Option[Any] = macro impl + } + } + + def impl(c: Context)(x: c.Expr[Any]): c.Expr[Option[Any]] = { + import c.universe._ + import Flag._ + + // parts here will be string literals - static parts of the string interpolation + // e.g. for q"$x, $y" parts will be Literal(Constant("")), Literal(Constant(", ")) and Literal(Constant("")) + val Apply(Select(Select(Apply(_, List(Apply(_, parts))), _), _), _) = c.macroApplication + val nresults = parts.length - 1 + + def results() = + ((1 to (nresults - 1)).toList map (i => Literal(Constant(i)))) :+ // (n - 1) results of type Int + Apply(Ident(TermName("List")), List(Literal(Constant(nresults)))) // and also one result of a different type + def extractorBody() = + if (nresults == 0) Literal(Constant(true)) + else if (nresults == 1) Apply(Ident(TermName("Some")), results()) + else Apply(Ident(TermName("Some")), List(Apply(Ident(TermName("Tuple" + nresults)), results()))) + + val name = TermName(java.util.UUID.randomUUID().toString.replace("-", "")) + val mdef = ModuleDef(NoMods, name, Template(List(Select(Ident(TermName("scala")), TypeName("AnyRef"))), emptyValDef, List( + DefDef(Modifiers(), nme.CONSTRUCTOR, List(), List(List()), TypeTree(), + Block(List(pendingSuperCall), Literal(Constant(())))), + DefDef(Modifiers(), TermName("unapply"), List(), List(List(ValDef(Modifiers(PARAM), TermName("x"), Ident(TypeName("Any")), EmptyTree))), TypeTree(), + extractorBody())))) + c.introduceTopLevel(nme.EMPTY_PACKAGE_NAME.toString, mdef) + c.Expr[Option[Any]](Apply(Select(Ident(name), TermName("unapply")), List(x.tree))) + } +}
\ No newline at end of file diff --git a/test/files/run/macro-expand-unapply-b/Test_2.scala b/test/files/run/macro-expand-unapply-b/Test_2.scala new file mode 100644 index 0000000000..5352160dfe --- /dev/null +++ b/test/files/run/macro-expand-unapply-b/Test_2.scala @@ -0,0 +1,8 @@ +object Test extends App { + import Macros._ + def whatever() = null + val q"$x1, $y1" = whatever() + println(x1, y1) + val q"$x2" = whatever() + println(x2) +} diff --git a/test/files/run/macro-repl-dontexpand.check b/test/files/run/macro-repl-dontexpand.check index 628a9146c4..99b70ea3dc 100644 --- a/test/files/run/macro-repl-dontexpand.check +++ b/test/files/run/macro-repl-dontexpand.check @@ -7,6 +7,6 @@ scala> def bar(c: scala.reflect.macros.Context) = ??? bar: (c: scala.reflect.macros.Context)Nothing scala> def foo = macro bar -foo: Any +defined term macro foo: Any scala> diff --git a/test/files/run/t5353.check b/test/files/run/t5353.check new file mode 100644 index 0000000000..a2906793ed --- /dev/null +++ b/test/files/run/t5353.check @@ -0,0 +1,2 @@ +1 +[Ljava.lang.Object; cannot be cast to [Ljava.lang.String; diff --git a/test/files/run/t5353.scala b/test/files/run/t5353.scala new file mode 100644 index 0000000000..5208fe527f --- /dev/null +++ b/test/files/run/t5353.scala @@ -0,0 +1,9 @@ +object Test extends App { + def f(x: Boolean) = if (x) Array("abc") else Array() + try { + println(f(true).length) + println(f(false).length) + } catch { + case ex: Throwable => println(ex.getMessage) + } +} diff --git a/test/files/run/t6381.check b/test/files/run/t6381.check index b51cfd0398..5070b67e46 100644 --- a/test/files/run/t6381.check +++ b/test/files/run/t6381.check @@ -9,7 +9,7 @@ scala> def pos_impl(c: reflect.macros.Context): c.Expr[String] = pos_impl: (c: scala.reflect.macros.Context)c.Expr[String] scala> def pos = macro pos_impl -pos: String +defined term macro pos: String scala> pos res0: String = class scala.reflect.internal.util.RangePosition diff --git a/test/files/run/t6955.check b/test/files/run/t6955.check new file mode 100644 index 0000000000..0cfbf08886 --- /dev/null +++ b/test/files/run/t6955.check @@ -0,0 +1 @@ +2 diff --git a/test/files/run/t6955.scala b/test/files/run/t6955.scala new file mode 100644 index 0000000000..980aa420cc --- /dev/null +++ b/test/files/run/t6955.scala @@ -0,0 +1,28 @@ +import scala.tools.partest.IcodeTest + +// this class should compile to code that uses switches (twice) +class Switches { + type Tag = Byte + + def switchBad(i: Tag): Int = i match { // notice type of i is Tag = Byte + case 1 => 1 + case 2 => 2 + case 3 => 3 + case _ => 0 + } + + // this worked before, should keep working + def switchOkay(i: Byte): Int = i match { + case 1 => 1 + case 2 => 2 + case 3 => 3 + case _ => 0 + } +} + +object Test extends IcodeTest { + // ensure we get two switches out of this -- ignore the rest of the output for robustness + // exclude the constant we emit for the "SWITCH ..." string below (we get the icode for all the code you see in this file) + override def show() = println(collectIcode("").filter(x => x.indexOf("SWITCH ...") >= 0 && x.indexOf("CONSTANT(") == -1).size) +} + |