From ce90a46a6964e524933ffe193ac38d58d3df07be Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Wed, 15 Aug 2012 15:29:54 +0200 Subject: adds the `skipPackage` attribute to Scaladoc Present in http://www.slideshare.net/VladUreche/scaladoc-reflection but not actually implemented in the ant task. Seems to be overlooked. --- src/compiler/scala/tools/ant/Scaladoc.scala | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/compiler/scala/tools/ant/Scaladoc.scala b/src/compiler/scala/tools/ant/Scaladoc.scala index b96ac6f29b..b2c6441222 100644 --- a/src/compiler/scala/tools/ant/Scaladoc.scala +++ b/src/compiler/scala/tools/ant/Scaladoc.scala @@ -44,7 +44,8 @@ import scala.tools.nsc.reporters.{Reporter, ConsoleReporter} * - `docgenerator`, * - `docrootcontent`, * - `unchecked`, - * - `nofail`. + * - `nofail`, + * - `skipPackages`. * * It also takes the following parameters as nested elements: * - `src` (for srcdir), @@ -159,6 +160,9 @@ class Scaladoc extends ScalaMatchingTask { /** Instruct the scaladoc tool to group similar functions together */ private var docGroups: Boolean = false + /** Instruct the scaladoc tool to skip certain packages */ + private var docSkipPackages: String = "" + /*============================================================================*\ ** Properties setters ** \*============================================================================*/ @@ -442,6 +446,12 @@ class Scaladoc extends ScalaMatchingTask { def setGroups(input: String) = docGroups = Flag.getBooleanValue(input, "groups") + /** Instruct the scaladoc tool to skip certain packages. + * @param input A colon-delimited list of fully qualified package names that will be skipped from scaladoc. + */ + def setSkipPackages(input: String) = + docSkipPackages = input + /*============================================================================*\ ** Properties getters ** \*============================================================================*/ @@ -642,6 +652,7 @@ class Scaladoc extends ScalaMatchingTask { docSettings.docRawOutput.value = docRawOutput docSettings.docNoPrefixes.value = docNoPrefixes docSettings.docGroups.value = docGroups + docSettings.docSkipPackages.value = docSkipPackages if(!docDiagramsDotPath.isEmpty) docSettings.docDiagramsDotPath.value = docDiagramsDotPath.get if (!docgenerator.isEmpty) docSettings.docgenerator.value = docgenerator.get -- cgit v1.2.3 From 46d57d47e81c8794a9a3594e080576788cc92324 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Wed, 15 Aug 2012 13:37:26 +0200 Subject: cleanup of reflection- and macro-related stuff mostly removes [Eugene] marks that I left back then and reviews related code some of those tokens got left in place, because I don't know to how fix them without imposing risks on 2.10.0 --- build.xml | 1 + .../reflect/macros/runtime/Infrastructure.scala | 14 +--- .../scala/reflect/macros/runtime/Settings.scala | 5 +- .../scala/reflect/macros/util/Traces.scala | 5 -- src/compiler/scala/reflect/reify/Reifier.scala | 8 +- .../scala/reflect/reify/codegen/GenSymbols.scala | 1 + .../scala/reflect/reify/codegen/GenTypes.scala | 3 +- .../scala/reflect/reify/phases/Calculate.scala | 2 +- .../scala/reflect/reify/phases/Reshape.scala | 3 +- .../scala/reflect/reify/utils/NodePrinters.scala | 1 + src/compiler/scala/tools/nsc/Global.scala | 14 +--- .../scala/tools/nsc/ast/NodePrinters.scala | 3 +- src/compiler/scala/tools/nsc/ast/Positions.scala | 7 -- src/compiler/scala/tools/nsc/ast/Trees.scala | 5 +- .../scala/tools/nsc/ast/parser/TreeBuilder.scala | 5 +- .../doc/model/ModelFactoryImplicitSupport.scala | 2 +- .../scala/tools/nsc/interpreter/IMain.scala | 2 +- .../scala/tools/nsc/interpreter/TypeStrings.scala | 2 +- .../tools/nsc/transform/SpecializeTypes.scala | 12 +-- .../scala/tools/nsc/typechecker/Implicits.scala | 7 +- .../scala/tools/nsc/typechecker/Macros.scala | 24 +++--- .../tools/nsc/typechecker/MethodSynthesis.scala | 14 +--- .../tools/nsc/typechecker/SyntheticMethods.scala | 4 +- .../tools/nsc/typechecker/TypeDiagnostics.scala | 1 - .../scala/tools/nsc/typechecker/Typers.scala | 9 +-- .../scala/tools/reflect/MacroImplementations.scala | 7 +- .../scala/tools/reflect/ToolBoxFactory.scala | 8 +- src/library/scala/reflect/ScalaLongSignature.java | 3 - src/library/scala/reflect/ScalaSignature.java | 2 - src/library/scala/reflect/base/Base.scala | 35 ++++----- src/library/scala/reflect/base/BuildUtils.scala | 8 +- src/library/scala/reflect/base/Exprs.scala | 5 +- src/library/scala/reflect/base/MirrorOf.scala | 2 - src/library/scala/reflect/base/Positions.scala | 5 -- .../scala/reflect/base/StandardDefinitions.scala | 54 +++++++------ src/library/scala/reflect/base/Symbols.scala | 5 +- src/library/scala/reflect/base/TagInterop.scala | 5 +- src/library/scala/reflect/base/Trees.scala | 6 -- src/library/scala/reflect/base/TypeTags.scala | 5 +- src/library/scala/reflect/base/Types.scala | 2 +- .../scala/reflect/macros/internal/package.scala | 2 - src/library/scala/util/Marshal.scala | 2 - src/reflect/scala/reflect/api/FrontEnds.scala | 2 - src/reflect/scala/reflect/api/Importers.scala | 2 - src/reflect/scala/reflect/api/JavaUniverse.scala | 2 - src/reflect/scala/reflect/api/Mirrors.scala | 14 +--- src/reflect/scala/reflect/api/Positions.scala | 12 +-- src/reflect/scala/reflect/api/Symbols.scala | 3 +- src/reflect/scala/reflect/api/TagInterop.scala | 8 +- src/reflect/scala/reflect/api/Types.scala | 1 - .../scala/reflect/internal/Definitions.scala | 89 +++++----------------- src/reflect/scala/reflect/internal/Importers.scala | 3 +- src/reflect/scala/reflect/internal/Printers.scala | 9 +-- src/reflect/scala/reflect/internal/StdNames.scala | 2 - src/reflect/scala/reflect/internal/Symbols.scala | 1 - src/reflect/scala/reflect/internal/Trees.scala | 7 +- src/reflect/scala/reflect/internal/Types.scala | 10 +-- .../scala/reflect/macros/Infrastructure.scala | 4 - src/reflect/scala/reflect/macros/Settings.scala | 8 +- src/reflect/scala/reflect/macros/TreeBuilder.scala | 4 - .../scala/reflect/runtime/JavaMirrors.scala | 57 ++++++-------- .../scala/reflect/runtime/SymbolLoaders.scala | 6 +- .../scala/reflect/runtime/SynchronizedOps.scala | 1 + .../reflect/runtime/SynchronizedSymbols.scala | 2 - src/reflect/scala/reflect/runtime/package.scala | 2 - src/reflect/scala/tools/nsc/io/Path.scala | 2 - test/files/run/reify_ann1a.scala | 1 + test/files/run/reify_ann1b.scala | 1 + test/files/run/reify_ann2a.scala | 1 + test/files/run/reify_ann3.scala | 1 + test/files/run/reify_ann4.scala | 1 + test/files/run/reify_ann5.scala | 1 + 72 files changed, 168 insertions(+), 399 deletions(-) diff --git a/build.xml b/build.xml index d95c6ab19c..647697bed5 100644 --- a/build.xml +++ b/build.xml @@ -2178,6 +2178,7 @@ DOCUMENTATION docfooter="epfl" docsourceurl="${scaladoc.url}€{FILE_PATH}.scala#L1" docUncompilable="${src.dir}/library-aux" + skipPackages="scala.reflect.macros" sourcepath="${src.dir}" classpathref="pack.classpath" addparams="${scalac.args.all}" diff --git a/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala b/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala index 19fb03364e..0a8a8d015d 100644 --- a/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala +++ b/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala @@ -18,19 +18,7 @@ trait Infrastructure { val libraryClassPath: List[java.net.URL] = universe.classPath.asURLs - lazy val libraryClassLoader: ClassLoader = { - val classpath = libraryClassPath - var loader: ClassLoader = ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader) - - // [Eugene] a heuristic to detect REPL - if (universe.settings.exposeEmptyPackage.value) { - import scala.tools.nsc.interpreter._ - val virtualDirectory = universe.settings.outputDirs.getSingleOutput.get - loader = new AbstractFileClassLoader(virtualDirectory, loader) {} - } - - loader - } + lazy val libraryClassLoader: ClassLoader = universe.analyzer.macroClassloader type Run = universe.Run diff --git a/src/compiler/scala/reflect/macros/runtime/Settings.scala b/src/compiler/scala/reflect/macros/runtime/Settings.scala index 9c24273cd7..c602532ea4 100644 --- a/src/compiler/scala/reflect/macros/runtime/Settings.scala +++ b/src/compiler/scala/reflect/macros/runtime/Settings.scala @@ -13,18 +13,17 @@ trait Settings { def compilerSettings: List[String] = universe.settings.recreateArgs def setCompilerSettings(options: String): this.type = - // todo. is not going to work with quoted arguments with embedded whitespaces + // SI-5925: doesn't work with arguments that contains whitespaces setCompilerSettings(options.split(" ").toList) def setCompilerSettings(options: List[String]): this.type = { val settings = new tools.nsc.Settings(_ => ()) - // [Eugene] what settings should we exclude? settings.copyInto(universe.settings) this } def withCompilerSettings[T](options: String)(op: => T): T = - // todo. is not going to work with quoted arguments with embedded whitespaces + // SI-5925: doesn't work with arguments that contains whitespaces withCompilerSettings(options.split(" ").toList)(op) def withCompilerSettings[T](options: List[String])(op: => T): T = { diff --git a/src/compiler/scala/reflect/macros/util/Traces.scala b/src/compiler/scala/reflect/macros/util/Traces.scala index 6c2f115994..078cd2b74f 100644 --- a/src/compiler/scala/reflect/macros/util/Traces.scala +++ b/src/compiler/scala/reflect/macros/util/Traces.scala @@ -4,11 +4,6 @@ package util trait Traces { def globalSettings: tools.nsc.Settings - // [Eugene] lots of ways to log: - // 1) trace(...) - // 2) log(...) - // 3) if (foo) { doStuff(); includingSomeLogs(); } - // what is the conventional way of unifying this? val macroDebugLite = globalSettings.YmacrodebugLite.value val macroDebugVerbose = globalSettings.YmacrodebugVerbose.value val macroTraceLite = scala.tools.nsc.util.trace when (macroDebugLite || macroDebugVerbose) diff --git a/src/compiler/scala/reflect/reify/Reifier.scala b/src/compiler/scala/reflect/reify/Reifier.scala index 53e01309cb..f602fe9b99 100644 --- a/src/compiler/scala/reflect/reify/Reifier.scala +++ b/src/compiler/scala/reflect/reify/Reifier.scala @@ -52,7 +52,6 @@ abstract class Reifier extends States */ lazy val reification: Tree = { try { - // [Eugene] conventional way of doing this? if (universe exists (_.isErroneous)) CannotReifyErroneousPrefix(universe) if (universe.tpe == null) CannotReifyUntypedPrefix(universe) @@ -62,7 +61,6 @@ abstract class Reifier extends States reifyTrace("reifee is located at: ")(tree.pos) reifyTrace("universe = ")(universe) reifyTrace("mirror = ")(mirror) - // [Eugene] conventional way of doing this? if (tree exists (_.isErroneous)) CannotReifyErroneousReifee(tree) if (tree.tpe == null) CannotReifyUntypedReifee(tree) val pipeline = mkReificationPipeline @@ -108,11 +106,7 @@ abstract class Reifier extends States // // todo. this is a common problem with non-trivial macros in our current macro system // needs to be solved some day - // - // list of non-hygienic transformations: - // todo. to be updated - // [Eugene++] yeah, ugly and extremely brittle, but we do need to do resetAttrs. will be fixed later - // todo. maybe try `resetLocalAttrs` once the dust settles + // maybe try `resetLocalAttrs` once the dust settles var importantSymbols = Set[Symbol]( NothingClass, AnyClass, SingletonClass, PredefModule, ScalaRunTimeModule, TypeCreatorClass, TreeCreatorClass, MirrorOfClass, BaseUniverseClass, JavaUniverseClass, ReflectRuntimePackage, ReflectRuntimeCurrentMirror) diff --git a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala index 7f066a2cc3..ca6e14cfd3 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala @@ -72,6 +72,7 @@ trait GenSymbols { */ val hasPackagelessParent = sym.ownerChain.tail.tail exists (_.isEmptyPackageClass) if (sym.isStatic && (sym.isClass || sym.isModule) && !hasPackagelessParent) { + // SI-6238: if applicable, emit references to StandardDefinitions instead of staticClass/staticModule calls val resolver = if (sym.isType) nme.staticClass else nme.staticModule mirrorMirrorCall(resolver, reify(sym.fullName)) } else { diff --git a/src/compiler/scala/reflect/reify/codegen/GenTypes.scala b/src/compiler/scala/reflect/reify/codegen/GenTypes.scala index c762a28f99..1d2e177688 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenTypes.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenTypes.scala @@ -23,7 +23,7 @@ trait GenTypes { if (isSemiConcreteTypeMember(tpe)) return reifySemiConcreteTypeMember(tpe) - // [Eugene] how do I check that the substitution is legal w.r.t tpe.info? + // SI-6242: splicing might violate type bounds val spliced = spliceType(tpe) if (spliced != EmptyTree) return spliced @@ -69,7 +69,6 @@ trait GenTypes { def reificationIsConcrete: Boolean = state.reificationIsConcrete def spliceType(tpe: Type): Tree = { - // [Eugene] it seems that depending on the context the very same symbol can be either a spliceable tparam or a quantified existential. very weird! val quantified = currentQuantified if (tpe.isSpliceable && !(quantified contains tpe.typeSymbol)) { if (reifyDebug) println("splicing " + tpe) diff --git a/src/compiler/scala/reflect/reify/phases/Calculate.scala b/src/compiler/scala/reflect/reify/phases/Calculate.scala index 41cf6c066a..4d1e22abe7 100644 --- a/src/compiler/scala/reflect/reify/phases/Calculate.scala +++ b/src/compiler/scala/reflect/reify/phases/Calculate.scala @@ -9,7 +9,7 @@ trait Calculate { implicit class RichCalculateSymbol(sym: Symbol) { def metalevel: Int = { assert(sym != null && sym != NoSymbol); localSymbols.getOrElse(sym, 0) } - def isLocalToReifee = (localSymbols contains sym) // [Eugene] how do I account for local skolems? + def isLocalToReifee = (localSymbols contains sym) // todo. how do I account for local skolems? } implicit class RichCalculateType(tpe: Type) { diff --git a/src/compiler/scala/reflect/reify/phases/Reshape.scala b/src/compiler/scala/reflect/reify/phases/Reshape.scala index e26dd7e227..fcf3c0e65c 100644 --- a/src/compiler/scala/reflect/reify/phases/Reshape.scala +++ b/src/compiler/scala/reflect/reify/phases/Reshape.scala @@ -248,7 +248,6 @@ trait Reshape { New(TypeTree(ann.atp) setOriginal extractOriginal(ann.original), List(args)) } - // [Eugene] is this implemented correctly? private def trimAccessors(deff: Tree, stats: List[Tree]): List[Tree] = { val symdefs = (stats collect { case vodef: ValOrDefDef => vodef } map (vodeff => vodeff.symbol -> vodeff)).toMap val accessors = collection.mutable.Map[ValDef, List[DefDef]]() @@ -287,7 +286,7 @@ trait Reshape { val name1 = nme.dropLocalSuffix(name) val vdef1 = ValDef(mods2, name1, tpt, rhs) if (reifyDebug) println("resetting visibility of field: %s => %s".format(vdef, vdef1)) - Some(vdef1) // no copyAttrs here, because new ValDef and old symbols are not out of sync + Some(vdef1) // no copyAttrs here, because new ValDef and old symbols are now out of sync case ddef @ DefDef(mods, name, tparams, vparamss, tpt, rhs) => if (accessors.values.exists(_.contains(ddef))) { if (reifyDebug) println("discarding accessor method: " + ddef) diff --git a/src/compiler/scala/reflect/reify/utils/NodePrinters.scala b/src/compiler/scala/reflect/reify/utils/NodePrinters.scala index 420f55c0e0..ec1f132c1b 100644 --- a/src/compiler/scala/reflect/reify/utils/NodePrinters.scala +++ b/src/compiler/scala/reflect/reify/utils/NodePrinters.scala @@ -23,6 +23,7 @@ trait NodePrinters { // depended upon. Of more fragile code I cannot conceive. // @Eugene: This stuff is only needed to debug-print out reifications in human-readable format // Rolling a full-fledged, robust TreePrinter would be several times more code. + // Also as of late we have tests that ensure that UX won't be broken by random changes to the reifier. val lines = (tree.toString.split(EOL) drop 1 dropRight 1).toList splitAt 2 var (List(universe, mirror), reification) = lines reification = (for (line <- reification) yield { diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index c60a3c941f..574129a2f1 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -43,8 +43,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) with DocComments with Positions { self => - // [Eugene++] would love to find better homes for the new things dumped into Global - // the mirror -------------------------------------------------- override def isCompilerUniverse = true @@ -62,16 +60,14 @@ class Global(var currentSettings: Settings, var reporter: Reporter) } def RootClass: ClassSymbol = rootMirror.RootClass def EmptyPackageClass: ClassSymbol = rootMirror.EmptyPackageClass - // [Eugene++] this little inconvenience gives us precise types for Expr.mirror and TypeTag.mirror - // by the way, is it possible to define variant type members? - - override def settings = currentSettings import definitions.findNamedMember def findMemberFromRoot(fullName: Name): Symbol = rootMirror.findMemberFromRoot(fullName) // alternate constructors ------------------------------------------ + override def settings = currentSettings + def this(reporter: Reporter) = this(new Settings(err => reporter.error(null, err)), reporter) @@ -873,8 +869,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) /** Is given package class a system package class that cannot be invalidated? */ private def isSystemPackageClass(pkg: Symbol) = - // [Eugene++ to Martin] please, verify -// was: pkg == definitions.RootClass || pkg == RootClass || pkg == definitions.ScalaPackageClass || { val pkgname = pkg.fullName @@ -937,8 +931,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) else new MergedClassPath(elems, classPath.context) val oldEntries = mkClassPath(subst.keys) val newEntries = mkClassPath(subst.values) - // [Eugene++ to Martin] please, verify -// was: reSync(definitions.RootClass, Some(classPath), Some(oldEntries), Some(newEntries), invalidated, failed) reSync(RootClass, Some(classPath), Some(oldEntries), Some(newEntries), invalidated, failed) } } @@ -998,8 +990,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) invalidateOrRemove(root) } else { if (classesFound) { - // [Eugene++ to Martin] please, verify -// was: if (root.isRoot) invalidateOrRemove(definitions.EmptyPackageClass) if (root.isRoot) invalidateOrRemove(EmptyPackageClass) else failed += root } diff --git a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala index 1fdf4c631e..0b54eda66d 100644 --- a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala @@ -145,8 +145,7 @@ abstract class NodePrinters { str.toString } def printModifiers(tree: MemberDef) { - // [Eugene++] there's most likely a bug here (?) - // see `Printers.printAnnotations` for more information + // SI-5885: by default this won't print annotations of not yet initialized symbols val annots0 = tree.symbol.annotations match { case Nil => tree.mods.annotations case xs => xs map annotationInfoToString diff --git a/src/compiler/scala/tools/nsc/ast/Positions.scala b/src/compiler/scala/tools/nsc/ast/Positions.scala index 74d1f8ab4b..d8fb632f73 100644 --- a/src/compiler/scala/tools/nsc/ast/Positions.scala +++ b/src/compiler/scala/tools/nsc/ast/Positions.scala @@ -11,13 +11,6 @@ trait Positions extends scala.reflect.internal.Positions { def validatePositions(tree: Tree) {} - // [Eugene] disabling this for now. imo it doesn't justify pollution of the public API - // override def _checkSetAnnotation(tree: Tree, annot: TreeAnnotation): Unit = { - // if (tree.pos != NoPosition && tree.pos != annot.pos) debugwarn("Overwriting annotation "+ tree.annotation +" of tree "+ tree +" with annotation "+ annot) - // // if ((tree.annotation.isInstanceOf[scala.reflect.internal.util.Position] || !annot.isInstanceOf[scala.reflect.internal.util.Position]) && tree.isInstanceOf[Block]) - // // println("Updating block from "+ tree.annotation +" to "+ annot) - // } - class ValidatingPosAssigner extends PosAssigner { var pos: Position = _ override def traverse(t: Tree) { diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 381b834a0c..6f17a7d625 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -117,10 +117,7 @@ trait Trees extends reflect.internal.Trees { self: Global => if (vparamss1.isEmpty || !vparamss1.head.isEmpty && vparamss1.head.head.mods.isImplicit) vparamss1 = List() :: vparamss1; val superRef: Tree = atPos(superPos)(gen.mkSuperSelect) - def mkApply(fun: Tree, args: List[Tree]) = Apply(fun, args) - val superCall = (superRef /: argss) (mkApply) - // [Eugene++] no longer compiles after I moved the `Apply` case class into scala.reflect.internal - // val superCall = (superRef /: argss) (Apply) + val superCall = (superRef /: argss) (Apply.apply) List( atPos(wrappingPos(superPos, lvdefs ::: argss.flatten)) ( DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(Constant()))))) diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index ab856f09b8..898045e410 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -546,10 +546,7 @@ abstract class TreeBuilder { rhs1, List( atPos(pat1.pos) { - def mkIdent(name: Name) = Ident(name) - CaseDef(pat1, EmptyTree, makeTupleTerm(vars map (_._1) map mkIdent, true)) - // [Eugene++] no longer compiles after I moved the `Ident` case class into scala.reflect.internal - // CaseDef(pat1, EmptyTree, makeTupleTerm(vars map (_._1) map Ident, true)) + CaseDef(pat1, EmptyTree, makeTupleTerm(vars map (_._1) map Ident.apply, true)) } )) } diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala index 327436ed20..89195020c4 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala @@ -176,7 +176,7 @@ trait ModelFactoryImplicitSupport { val appliedTree = new ApplyImplicitView(viewTree, List(Ident("") setType viewTree.tpe.paramTypes.head)) val appliedTreeTyped: Tree = { val newContext = context.makeImplicit(context.ambiguousErrors) - newContext.macrosEnabled = false // [Eugene] I assume you want macro signature, not macro expansion + newContext.macrosEnabled = false val newTyper = global.analyzer.newTyper(newContext) newTyper.silent(_.typed(appliedTree, global.analyzer.EXPRmode, WildcardType), false) match { diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index 6eadc1e63b..96d7dadbd7 100644 --- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala +++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala @@ -145,7 +145,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends private def _initSources = List(new BatchSourceFile("", "class $repl_$init { }")) private def _initialize() = { try { - // [Eugene] todo. if this crashes, REPL will hang + // todo. if this crashes, REPL will hang new _compiler.Run() compileSources _initSources _initializeComplete = true true diff --git a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala index d6604499b4..9dcc4006a3 100644 --- a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala +++ b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala @@ -213,7 +213,7 @@ trait TypeStrings { private def tparamString[T: ru.TypeTag] : String = { def typeArguments: List[ru.Type] = ru.typeOf[T] match { case ru.TypeRef(_, _, args) => args; case _ => Nil } - // [Eugene++] todo. need to use not the `rootMirror`, but a mirror with the REPL's classloader + // [Eugene to Paul] need to use not the `rootMirror`, but a mirror with the REPL's classloader // how do I get to it? acquiring context classloader seems unreliable because of multithreading def typeVariables: List[java.lang.Class[_]] = typeArguments map (targ => ru.rootMirror.runtimeClass(targ)) brackets(typeArguments map (jc => tvarString(List(jc))): _*) diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index db97308f41..282c7251e3 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -436,7 +436,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { val sClassMap = anyrefSpecCache.getOrElseUpdate(sClass, mutable.Map[Symbol, Symbol]()) sClassMap.getOrElseUpdate(tparam, - tparam.cloneSymbol(sClass, tparam.flags, (tparam.name append tpnme.SPECIALIZED_SUFFIX).asInstanceOf[Name]) // [Eugene++] why do we need this cast? + tparam.cloneSymbol(sClass, tparam.flags, (tparam.name append tpnme.SPECIALIZED_SUFFIX).asInstanceOf[Name]) // [Eugene] why do we need this cast? modifyInfo (info => TypeBounds(info.bounds.lo, AnyRefClass.tpe)) ).tpe } @@ -1772,10 +1772,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { private def forwardCall(pos: scala.reflect.internal.util.Position, receiver: Tree, paramss: List[List[ValDef]]): Tree = { val argss = mmap(paramss)(x => Ident(x.symbol)) - def mkApply(fun: Tree, args: List[Tree]) = Apply(fun, args) - atPos(pos) { (receiver /: argss) (mkApply) } - // [Eugene++] no longer compiles after I moved the `Apply` case class into scala.reflect.internal - // atPos(pos) { (receiver /: argss) (Apply) } + atPos(pos) { (receiver /: argss) (Apply.apply) } } /** Forward to the generic class constructor. If the current class initializes @@ -1817,10 +1814,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { else Ident(x.symbol) ) - def mkApply(fun: Tree, args: List[Tree]) = Apply(fun, args) - atPos(pos) { (receiver /: argss) (mkApply) } - // [Eugene++] no longer compiles after I moved the `Apply` case class into scala.reflect.internal - // atPos(pos) { (receiver /: argss) (Apply) } + atPos(pos) { (receiver /: argss) (Apply.apply) } } /** Add method m to the set of symbols for which we need an implementation tree diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index f9035f26b9..924d590edb 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -1185,10 +1185,6 @@ trait Implicits { // ClassTags are not path-dependent, so their materializer doesn't care about prefixes if (tagClass eq ClassTagClass) gen.mkBasisUniverseRef else pre match { - // [Eugene to Martin] this is the crux of the interaction between - // implicits and reifiers here we need to turn a (supposedly - // path-dependent) type into a tree that will be used as a prefix I'm - // not sure if I've done this right - please, review case SingleType(prePre, preSym) => gen.mkAttributedRef(prePre, preSym) setType pre // necessary only to compile typetags used inside the Universe cake @@ -1373,7 +1369,8 @@ trait Implicits { /** The result of the implicit search: * First search implicits visible in current context. * If that fails, search implicits in expected type `pt`. - * // [Eugene] the following lines should be deleted after we migrate delegate tag materialization to implicit macros + * + * todo. the following lines should be deleted after we migrate delegate tag materialization to implicit macros * If that fails, and `pt` is an instance of a ClassTag, try to construct a class tag. * If that fails, and `pt` is an instance of a TypeTag, try to construct a type tag. * If that fails, and `pt` is an instance of a ClassManifest, try to construct a class manifest. diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index c8bf70e9e0..c2ab5edbb6 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -132,9 +132,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { // there are some more clever cases when seemingly non-static method ends up being statically accessible // however, the code below doesn't account for these guys, because it'd take a look of time to get it right // for now I leave it as a todo and move along to more the important stuff - // [Eugene] relies on the fact that macro implementations can only be defined in static classes - // [Martin to Eugene++] There's similar logic buried in Symbol#flatname. Maybe we can refactor? - // [Eugene] we will refactor once I get my hands on https://issues.scala-lang.org/browse/SI-5498 + // todo. refactor when fixing SI-5498 def className: String = { def loop(sym: Symbol): String = sym match { case sym if sym.owner.isPackageClass => @@ -445,7 +443,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { // because it's adapt which is responsible for automatic expansion during typechecking def typecheckRhs(rhs: Tree): Tree = { try { - val prevNumErrors = reporter.ERROR.count // [Eugene] funnily enough, the isErroneous check is not enough + val prevNumErrors = reporter.ERROR.count var rhs1 = if (hasError) EmptyTree else typer.typed1(rhs, EXPRmode, WildcardType) def typecheckedWithErrors = (rhs1 exists (_.isErroneous)) || reporter.ERROR.count != prevNumErrors def rhsNeedsMacroExpansion = rhs1.symbol != null && rhs1.symbol.isTermMacro && !rhs1.symbol.isErroneous @@ -681,8 +679,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { // transform type parameters of a macro implementation into type parameters of a macro definition runtimeType = runtimeType map { case TypeRef(pre, sym, args) => - // [Eugene] not sure which of these deSkolemizes are necessary - // sym.paramPos is unreliable (see another case below) + // sym.paramPos is unreliable (see an example in `macroArgs`) val tparams = macroImpl.typeParams map (_.deSkolemize) val paramPos = tparams indexOf sym.deSkolemize val sym1 = @@ -745,7 +742,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { * Loads classes from from -cp (aka the library classpath). * Is also capable of detecting REPL and reusing its classloader. */ - private lazy val macroClassloader: ClassLoader = { + lazy val macroClassloader: ClassLoader = { if (global.forMSIL) throw new UnsupportedOperationException("Scala reflection not available on this platform") @@ -753,7 +750,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { macroLogVerbose("macro classloader: initializing from -cp: %s".format(classpath)) val loader = ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader) - // [Eugene] a heuristic to detect the REPL + // a heuristic to detect the REPL if (global.settings.exposeEmptyPackage.value) { macroLogVerbose("macro classloader: initializing from a REPL classloader".format(global.classPath.asURLs)) import scala.tools.nsc.interpreter._ @@ -787,9 +784,11 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { val methName = binding.methName macroLogVerbose(s"resolved implementation as $className.$methName") - // [Eugene++] I don't use Scala reflection here, because it seems to interfere with JIT magic + // I don't use Scala reflection here, because it seems to interfere with JIT magic // whenever you instantiate a mirror (and not do anything with in, just instantiate), performance drops by 15-20% // I'm not sure what's the reason - for me it's pure voodoo + // upd. my latest experiments show that everything's okay + // it seems that in 2.10.1 we can easily switch to Scala reflection try { macroTraceVerbose("loading implementation class: ")(className) macroTraceVerbose("classloader is: ")(ReflectionUtils.show(macroClassloader)) @@ -889,7 +888,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { val targ = binding.targs(paramPos).tpe.typeSymbol val tpe = if (targ.isTypeParameterOrSkolem) { if (targ.owner == macroDef) { - // [Eugene] doesn't work when macro def is compiled separately from its usages + // doesn't work when macro def is compiled separately from its usages // then targ is not a skolem and isn't equal to any of macroDef.typeParams // val argPos = targ.deSkolemize.paramPos val argPos = macroDef.typeParams.indexWhere(_.name == targ.name) @@ -970,7 +969,6 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { // so I added this dummy local for the ease of debugging var expectedTpe = expandee.tpe - // [Eugene] weird situation. what's the conventional way to deal with it? val isNullaryInvocation = expandee match { case TypeApply(Select(_, _), _) => true case TypeApply(Ident(_), _) => true @@ -1117,8 +1115,9 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { macroLogLite("typechecking macro expansion %s at %s".format(expandee, expandee.pos)) macroArgs(typer, expandee).fold(failExpansion(): MacroExpansionResult) { args => (args: @unchecked) match { - // [Eugene++] crashes virtpatmat: + // crashes virtpatmat: // case args @ ((context: MacroContext) :: _) => + // todo. extract a minimized test case case args @ (context0 :: _) => val context = context0.asInstanceOf[MacroContext] if (nowDelayed) { @@ -1197,7 +1196,6 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { } private def handleMacroExpansionException(typer: Typer, expandee: Tree, ex: Throwable): MacroExpansionResult = { - // [Eugene] any ideas about how to improve this one? val realex = ReflectionUtils.unwrapThrowable(ex) realex match { case realex: reflect.macros.runtime.AbortMacroException => diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index dd180e6b76..f7ba189e0f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -31,7 +31,6 @@ trait MethodSynthesis { else DefDef(sym, body) def applyTypeInternal(tags: List[TT[_]]): Type = { - // [Eugene++ to Paul] needs review!! val symbols = tags map compilerSymbolFromTag val container :: args = symbols val tparams = container.typeConstructor.typeParams @@ -53,21 +52,14 @@ trait MethodSynthesis { applyTypeInternal(List(t1)) def applyType[CC[X1], X1](implicit t1: TT[CC[_]], t2: TT[X1]): Type = - applyTypeInternal(List[TT[_]](t1, t2)) + applyTypeInternal(List(t1, t2)) def applyType[CC[X1, X2], X1, X2](implicit t1: TT[CC[_,_]], t2: TT[X1], t3: TT[X2]): Type = - // [Eugene++] without an explicit type annotation for List, we get this: - // [scalacfork] C:\Projects\KeplerUnderRefactoring\src\compiler\scala\tools\nsc\typechecker\MethodSynthesis.scala:59: error: no type parameters for method apply: (xs: A*)List[A] in object List exist so that it can be applied to arguments (scala.tools.nsc.typechecker.MethodSynthesis.synthesisUtil.TT[CC[_, _]], scala.tools.nsc.typechecker.MethodSynthesis.synthesisUtil.TT[X1], scala.tools.nsc.typechecker.MethodSynthesis.synthesisUtil.TT[X2]) - // [scalacfork] --- because --- - // [scalacfork] undetermined type - // [scalacfork] applyTypeInternal(List(t1, t2, t3)) - applyTypeInternal(List[TT[_]](t1, t2, t3)) + applyTypeInternal(List(t1, t2, t3)) def applyType[CC[X1, X2, X3], X1, X2, X3](implicit t1: TT[CC[_,_,_]], t2: TT[X1], t3: TT[X2], t4: TT[X3]): Type = - applyTypeInternal(List[TT[_]](t1, t2, t3, t4)) + applyTypeInternal(List(t1, t2, t3, t4)) - // [Martin->Eugene] !!! reinstantiate when typeables are in. - // [Eugene++->Martin] now this compiles, will soon check it out def newMethodType[F](owner: Symbol)(implicit t: TT[F]): Type = { val fnSymbol = compilerSymbolFromTag(t) val formals = compilerTypeFromTag(t).typeArguments diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala index c7c9d2f4aa..d227f485c2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala @@ -63,7 +63,7 @@ trait SyntheticMethods extends ast.TreeDSL { // in the original order. def accessors = clazz.caseFieldAccessors sortBy { acc => originalAccessors indexWhere { orig => - (acc.name == orig.name) || (acc.name startsWith (orig.name append "$").asInstanceOf[Name]) // [Eugene++] why do we need this cast? + (acc.name == orig.name) || (acc.name startsWith (orig.name append "$").asInstanceOf[Name]) // [Eugene] why do we need this cast? } } val arity = accessors.size @@ -87,7 +87,7 @@ trait SyntheticMethods extends ast.TreeDSL { ) def forwardToRuntime(method: Symbol): Tree = - forwardMethod(method, getMember(ScalaRunTimeModule, (method.name prepend "_").asInstanceOf[Name]))(mkThis :: _) // [Eugene++] why do we need this cast? + forwardMethod(method, getMember(ScalaRunTimeModule, (method.name prepend "_").asInstanceOf[Name]))(mkThis :: _) // [Eugene] why do we need this cast? def callStaticsMethod(name: String)(args: Tree*): Tree = { val method = termMember(RuntimeStaticsModule, name) diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala index 4a0977eb90..f0dca64a00 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala @@ -462,7 +462,6 @@ trait TypeDiagnostics { case CyclicReference(sym, info: TypeCompleter) => if (context0.owner.isTermMacro) { // see comments to TypeSigError for an explanation of this special case - // [Eugene] is there a better way? throw ex } else { val pos = info.tree match { diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index a6d7fcda75..7c509f4d33 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -51,7 +51,6 @@ trait Typers extends Modes with Adaptations with Tags { transformed.clear() } - // [Eugene] shouldn't this be converted to resetAllAttrs? object UnTyper extends Traverser { override def traverse(tree: Tree) = { if (tree != EmptyTree) tree.tpe = null @@ -909,7 +908,7 @@ trait Typers extends Modes with Adaptations with Tags { def adaptType(): Tree = { if (inFunMode(mode)) { - // [Eugene++] the commented line below makes sense for typechecking, say, TypeApply(Ident(`some abstract type symbol`), List(...)) + // 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 @@ -2609,7 +2608,7 @@ trait Typers extends Modes with Adaptations with Tags { val stats1 = typedStats(stats, NoSymbol) // this code kicks in only after typer, so `stats` will never be filled in time // as a result, most of compound type trees with non-empty stats will fail to reify - // [Eugene++] todo. investigate whether something can be done about this + // todo. investigate whether something can be done about this val att = templ.attachments.get[CompoundTypeTreeOriginalAttachment].getOrElse(CompoundTypeTreeOriginalAttachment(Nil, Nil)) templ.removeAttachment[CompoundTypeTreeOriginalAttachment] templ addAttachment att.copy(stats = stats1) @@ -3416,7 +3415,7 @@ trait Typers extends Modes with Adaptations with Tags { } if (hasError) annotationError - else AnnotationInfo(annType, List(), nvPairs map {p => (p._1.asInstanceOf[Name], p._2.get)}).setOriginal(Apply(typedFun, args).setPos(ann.pos)) // [Eugene+] why do we need this cast? + else AnnotationInfo(annType, List(), nvPairs map {p => (p._1.asInstanceOf[Name], p._2.get)}).setOriginal(Apply(typedFun, args).setPos(ann.pos)) // [Eugene] why do we need this cast? } } else if (requireJava) { reportAnnotationError(NestedAnnotationError(ann, annType)) @@ -5105,7 +5104,7 @@ trait Typers extends Modes with Adaptations with Tags { erasure.GenericArray.unapply(tpt.tpe).isDefined) => // !!! todo simplify by using extractor // convert new Array[T](len) to evidence[ClassTag[T]].newArray(len) // convert new Array^N[T](len) for N > 1 to evidence[ClassTag[Array[...Array[T]...]]].newArray(len), where Array HK gets applied (N-1) times - // [Eugene] no more MaxArrayDims. ClassTags are flexible enough to allow creation of arrays of arbitrary dimensionality (w.r.t JVM restrictions) + // no more MaxArrayDims. ClassTags are flexible enough to allow creation of arrays of arbitrary dimensionality (w.r.t JVM restrictions) val Some((level, componentType)) = erasure.GenericArray.unapply(tpt.tpe) val tagType = List.iterate(componentType, level)(tpe => appliedType(ArrayClass.toTypeConstructor, List(tpe))).last val newArrayApp = atPos(tree.pos) { diff --git a/src/compiler/scala/tools/reflect/MacroImplementations.scala b/src/compiler/scala/tools/reflect/MacroImplementations.scala index 40ceefcc70..48a4811744 100644 --- a/src/compiler/scala/tools/reflect/MacroImplementations.scala +++ b/src/compiler/scala/tools/reflect/MacroImplementations.scala @@ -6,11 +6,12 @@ import scala.collection.mutable.ListBuffer import scala.collection.mutable.Stack abstract class MacroImplementations { - val c: Context + val c: Context - import c.universe.{Position => SPosition, _} + import c.universe._ + import definitions._ - def macro_StringInterpolation_f(parts: List[Tree], args: List[Tree], origApplyPos: SPosition): Tree = { + def macro_StringInterpolation_f(parts: List[Tree], args: List[Tree], origApplyPos: c.universe.Position): Tree = { // the parts all have the same position information (as the expression is generated by the compiler) // the args have correct position information diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala index eeec973299..8cc5a4e531 100644 --- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala +++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala @@ -16,9 +16,6 @@ import scala.reflect.NameTransformer import scala.reflect.api.JavaUniverse import scala.reflect.base.MirrorOf -// [Eugene++ to Martin] by the way, toolboxes are unable to compile anything that involves packages -// is this intentional? - abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => val mirror: u.Mirror @@ -187,10 +184,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => val meth = obj.moduleClass.newMethod(newTermName(wrapperMethodName)) def makeParam(schema: (FreeTermSymbol, TermName)) = { val (fv, name) = schema - // [Eugene] conventional way of doing this? - val underlying = fv.tpe.resultType - val tpe = appliedType(definitions.FunctionClass(0).tpe, List(underlying)) - meth.newValueParameter(name) setInfo tpe + meth.newValueParameter(name) setInfo appliedType(definitions.FunctionClass(0).tpe, List(fv.tpe.resultType)) } meth setInfo MethodType(freeTerms.map(makeParam).toList, AnyClass.tpe) minfo.decls enter meth diff --git a/src/library/scala/reflect/ScalaLongSignature.java b/src/library/scala/reflect/ScalaLongSignature.java index fce58207f1..5b6d78f446 100644 --- a/src/library/scala/reflect/ScalaLongSignature.java +++ b/src/library/scala/reflect/ScalaLongSignature.java @@ -5,9 +5,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -/** - * [Martin to Eugene++] Todo: Move to somewhere else? -*/ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface ScalaLongSignature { diff --git a/src/library/scala/reflect/ScalaSignature.java b/src/library/scala/reflect/ScalaSignature.java index f0df99fe79..a8af554d2b 100644 --- a/src/library/scala/reflect/ScalaSignature.java +++ b/src/library/scala/reflect/ScalaSignature.java @@ -5,8 +5,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -/** * [Martin to Eugene++] Todo: Move to somewhere else? - */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface ScalaSignature { diff --git a/src/library/scala/reflect/base/Base.scala b/src/library/scala/reflect/base/Base.scala index 714fd365ef..798e257d1e 100644 --- a/src/library/scala/reflect/base/Base.scala +++ b/src/library/scala/reflect/base/Base.scala @@ -279,8 +279,6 @@ class Base extends Universe { self => val NoPosition = new Position - def atPos[T <: Tree](pos: Position)(tree: T): T = tree - private val generated = new mutable.HashMap[String, WeakReference[Symbol]] private def cached(name: String)(symExpr: => Symbol): Symbol = @@ -411,6 +409,22 @@ class Base extends Universe { self => lazy val ListClass = staticClass("scala.List") lazy val PredefModule = staticModule("scala.Predef") + + lazy val ByteTpe = TypeRef(ScalaPrefix, ByteClass, Nil) + lazy val ShortTpe = TypeRef(ScalaPrefix, ShortClass, Nil) + lazy val CharTpe = TypeRef(ScalaPrefix, CharClass, Nil) + lazy val IntTpe = TypeRef(ScalaPrefix, IntClass, Nil) + lazy val LongTpe = TypeRef(ScalaPrefix, LongClass, Nil) + lazy val FloatTpe = TypeRef(ScalaPrefix, FloatClass, Nil) + lazy val DoubleTpe = TypeRef(ScalaPrefix, DoubleClass, Nil) + lazy val BooleanTpe = TypeRef(ScalaPrefix, BooleanClass, Nil) + lazy val UnitTpe = TypeRef(ScalaPrefix, UnitClass, Nil) + lazy val AnyTpe = TypeRef(ScalaPrefix, AnyClass, Nil) + lazy val AnyValTpe = TypeRef(ScalaPrefix, AnyValClass, Nil) + lazy val NothingTpe = TypeRef(ScalaPrefix, NothingClass, Nil) + lazy val NullTpe = TypeRef(ScalaPrefix, NullClass, Nil) + lazy val ObjectTpe = TypeRef(JavaLangPrefix, ObjectClass, Nil) + lazy val AnyRefTpe = ObjectTpe } import definitions._ @@ -419,22 +433,6 @@ class Base extends Universe { self => private lazy val ScalaPrefix = thisModuleType("scala") private lazy val JavaLangPrefix = thisModuleType("java.lang") - lazy val ByteTpe = TypeRef(ScalaPrefix, ByteClass, Nil) - lazy val ShortTpe = TypeRef(ScalaPrefix, ShortClass, Nil) - lazy val CharTpe = TypeRef(ScalaPrefix, CharClass, Nil) - lazy val IntTpe = TypeRef(ScalaPrefix, IntClass, Nil) - lazy val LongTpe = TypeRef(ScalaPrefix, LongClass, Nil) - lazy val FloatTpe = TypeRef(ScalaPrefix, FloatClass, Nil) - lazy val DoubleTpe = TypeRef(ScalaPrefix, DoubleClass, Nil) - lazy val BooleanTpe = TypeRef(ScalaPrefix, BooleanClass, Nil) - lazy val UnitTpe = TypeRef(ScalaPrefix, UnitClass, Nil) - lazy val AnyTpe = TypeRef(ScalaPrefix, AnyClass, Nil) - lazy val AnyValTpe = TypeRef(ScalaPrefix, AnyValClass, Nil) - lazy val NothingTpe = TypeRef(ScalaPrefix, NothingClass, Nil) - lazy val NullTpe = TypeRef(ScalaPrefix, NullClass, Nil) - lazy val ObjectTpe = TypeRef(JavaLangPrefix, ObjectClass, Nil) - lazy val AnyRefTpe = ObjectTpe - private var nodeCount = 0 // not synchronized abstract class Tree extends TreeBase with Product { @@ -745,7 +743,6 @@ class Base extends Universe { self => implicit val ExistentialTypeTreeTag = ClassTag[ExistentialTypeTree](classOf[ExistentialTypeTree]) implicit val TypeTreeTag = ClassTag[TypeTree](classOf[TypeTree]) - // [Eugene++] to be removed after SI-5863 is fixed def ClassDef(sym: Symbol, impl: Template): ClassDef = ??? def ModuleDef(sym: Symbol, impl: Template): ModuleDef = ??? def ValDef(sym: Symbol, rhs: Tree): ValDef = ??? diff --git a/src/library/scala/reflect/base/BuildUtils.scala b/src/library/scala/reflect/base/BuildUtils.scala index eaba0ec2b7..98f32231ad 100644 --- a/src/library/scala/reflect/base/BuildUtils.scala +++ b/src/library/scala/reflect/base/BuildUtils.scala @@ -5,6 +5,10 @@ trait BuildUtils { self: Universe => val build: BuildBase + // this API abstracts away the functionality necessary for reification + // it's too gimmicky and unstructured to be exposed directly in the universe + // but we need it in a publicly available place for reification to work + abstract class BuildBase { /** Selects type symbol with given simple name `name` from the defined members of `owner`. */ @@ -53,7 +57,6 @@ trait BuildUtils { self: Universe => * the only usage for it is preserving the captured symbol for compile-time analysis * @param flags (optional) flags of the free variable * @param origin (optional) debug information that tells where this symbol comes from - * [Martin to Eugene: why needed?] */ def newFreeExistential(name: String, info: Type, value: => Any, flags: FlagSet = NoFlags, origin: String = null): FreeTypeSymbol @@ -68,9 +71,6 @@ trait BuildUtils { self: Universe => def flagsFromBits(bits: Long): FlagSet - // [Eugene++ to Martin] these are necessary for reification - // on a second thought, I added them to BuildUtils instead of base - def emptyValDef: ValDef def This(sym: Symbol): Tree diff --git a/src/library/scala/reflect/base/Exprs.scala b/src/library/scala/reflect/base/Exprs.scala index 47af4f3a9d..10c222722a 100644 --- a/src/library/scala/reflect/base/Exprs.scala +++ b/src/library/scala/reflect/base/Exprs.scala @@ -39,10 +39,7 @@ trait Exprs { self: Universe => otherMirror.universe.Expr[T](otherMirror1, treec)(tag1) } - lazy val tree: Tree = treec[Exprs.this.type](mirror) - // [Eugene++] this is important - // !!! remove when we have improved type inference for singletons - // search for .type] to find other instances + lazy val tree: Tree = treec(mirror) lazy val staticType: Type = implicitly[AbsTypeTag[T]].tpe def actualType: Type = treeType(tree) diff --git a/src/library/scala/reflect/base/MirrorOf.scala b/src/library/scala/reflect/base/MirrorOf.scala index 6dc8090eee..1e9619d062 100644 --- a/src/library/scala/reflect/base/MirrorOf.scala +++ b/src/library/scala/reflect/base/MirrorOf.scala @@ -1,8 +1,6 @@ package scala.reflect package base -// [Eugene++ to Martin] why was this a member of `scala.reflect`, but not `scala.reflect.base`? - abstract class MirrorOf[U <: base.Universe with Singleton] { /** .. */ val universe: U diff --git a/src/library/scala/reflect/base/Positions.scala b/src/library/scala/reflect/base/Positions.scala index cefeb51c9a..76a7382e9e 100644 --- a/src/library/scala/reflect/base/Positions.scala +++ b/src/library/scala/reflect/base/Positions.scala @@ -14,9 +14,4 @@ trait Positions { /** .. */ val NoPosition: Position - - /** Assigns a given position to all position-less nodes of a given AST. - */ - def atPos[T <: Tree](pos: Position)(tree: T): T - // [Eugene++] why do we have this in base? } diff --git a/src/library/scala/reflect/base/StandardDefinitions.scala b/src/library/scala/reflect/base/StandardDefinitions.scala index fe32fdb4c2..8f1c96ea3f 100644 --- a/src/library/scala/reflect/base/StandardDefinitions.scala +++ b/src/library/scala/reflect/base/StandardDefinitions.scala @@ -6,37 +6,12 @@ package scala.reflect package base -// [Eugene++] not sure whether we need this in the top level of the universe -trait StandardTypes { - self: Universe => - - val ByteTpe: Type - val ShortTpe: Type - val CharTpe: Type - val IntTpe: Type - val LongTpe: Type - val FloatTpe: Type - val DoubleTpe: Type - val BooleanTpe: Type - val UnitTpe: Type - - val AnyTpe: Type - val AnyValTpe: Type - val AnyRefTpe: Type - val ObjectTpe: Type - - val NothingTpe: Type - val NullTpe: Type -} - -trait StandardDefinitions extends StandardTypes { +trait StandardDefinitions { self: Universe => val definitions: DefinitionsBase - // [Eugene] todo. shortcut to these fields if possible when generating tags - // todo. also shortcut to StandardTypes, of course - trait DefinitionsBase { + trait DefinitionsBase extends StandardTypes { // packages def ScalaPackageClass: ClassSymbol def ScalaPackage: ModuleSymbol @@ -66,9 +41,32 @@ trait StandardDefinitions extends StandardTypes { def StringClass : ClassSymbol def ClassClass : ClassSymbol def ArrayClass : ClassSymbol - def ListClass : ClassSymbol // [Eugene] I'd say List has earned its right to be here + def ListClass : ClassSymbol // the Predef object def PredefModule: ModuleSymbol } + + trait StandardTypes { + // the scala value classes + val UnitTpe: Type + val ByteTpe: Type + val ShortTpe: Type + val CharTpe: Type + val IntTpe: Type + val LongTpe: Type + val FloatTpe: Type + val DoubleTpe: Type + val BooleanTpe: Type + + // top types + val AnyTpe: Type + val AnyValTpe: Type + val AnyRefTpe: Type + val ObjectTpe: Type + + // bottom types + val NothingTpe: Type + val NullTpe: Type + } } diff --git a/src/library/scala/reflect/base/Symbols.scala b/src/library/scala/reflect/base/Symbols.scala index fe857c540f..294fa19d62 100644 --- a/src/library/scala/reflect/base/Symbols.scala +++ b/src/library/scala/reflect/base/Symbols.scala @@ -3,9 +3,6 @@ package base trait Symbols { self: Universe => - // [Eugene++ to Martin] why is Symbol >: Null, whereas all other symbol types are not nullable? - // same question goes for Types - /** The abstract type of symbols representing declarations */ type Symbol >: Null <: SymbolBase @@ -266,7 +263,7 @@ trait Symbols { self: Universe => * by inspecting its `selfType.termSymbol`. */ def moduleClass: Symbol // needed for tree traversals - // [Eugene++] when this becomes `moduleClass: ClassSymbol`, it will be the happiest day in my life + // when this becomes `moduleClass: ClassSymbol`, it will be the happiest day in my life final override def isModule = true final override def asModule = this diff --git a/src/library/scala/reflect/base/TagInterop.scala b/src/library/scala/reflect/base/TagInterop.scala index a9f0b60fd2..ec054106eb 100644 --- a/src/library/scala/reflect/base/TagInterop.scala +++ b/src/library/scala/reflect/base/TagInterop.scala @@ -4,12 +4,9 @@ package base import scala.runtime.ScalaRunTime._ trait TagInterop { self: Universe => - // [Eugene++] `mirror` parameters are now of type `Any`, because I can't make these path-dependent types work + // todo. `mirror` parameters are now of type `Any`, because I can't make these path-dependent types work // if you're brave enough, replace `Any` with `Mirror`, recompile and run interop_typetags_are_manifests.scala - // [Eugene++] would be great if we could approximate the interop without any mirrors - // todo. think how to implement that - def typeTagToManifest[T: ClassTag](mirror: Any, tag: base.Universe # TypeTag[T]): Manifest[T] = throw new UnsupportedOperationException("This universe does not support tag -> manifest conversions. Use scala.reflect.runtime.universe from scala-reflect.jar.") diff --git a/src/library/scala/reflect/base/Trees.scala b/src/library/scala/reflect/base/Trees.scala index 70993fd77f..224965a2b7 100644 --- a/src/library/scala/reflect/base/Trees.scala +++ b/src/library/scala/reflect/base/Trees.scala @@ -5,10 +5,6 @@ package scala.reflect package base -// [Eugene++] of all reflection APIs, this one is in the biggest need of review and documentation - -// Syncnote: Trees are currently not thread-safe. -// [Eugene++] now when trees are finally abstract types, can we do something for this? trait Trees { self: Universe => /** The base API that all trees support */ @@ -81,7 +77,6 @@ trait Trees { self: Universe => * example is Parens, which is eliminated during parsing. */ type Tree >: Null <: TreeBase - // [Eugene++] todo. discuss nullability of abstract types /** A tag that preserves the identity of the `Tree` abstract type from erasure. * Can be used for pattern matching, instance tests, serialization and likes. @@ -1381,7 +1376,6 @@ trait Trees { self: Universe => /** ... */ lazy val NoMods = Modifiers() - // [Eugene++] temporarily moved here until SI-5863 is fixed // ---------------------- factories ---------------------------------------------- /** @param sym the class symbol diff --git a/src/library/scala/reflect/base/TypeTags.scala b/src/library/scala/reflect/base/TypeTags.scala index b673122d00..c9d1ccf5bc 100644 --- a/src/library/scala/reflect/base/TypeTags.scala +++ b/src/library/scala/reflect/base/TypeTags.scala @@ -99,9 +99,10 @@ import language.implicitConversions * 4) Certain manifest functions (such as `<:<`, `>:>` and `typeArguments`) weren't included in the tag API. * Consider using reflection API provided by Java (for classes) and Scala (for types) instead. */ -// [Eugene++] implement serialization for typetags trait TypeTags { self: Universe => + import definitions._ + /** * If an implicit value of type u.AbsTypeTag[T] is required, the compiler will make one up on demand. * The implicitly created value contains in its tpe field a value of type u.Type that is a reflective representation of T. @@ -164,7 +165,7 @@ trait TypeTags { self: Universe => } private class AbsTypeTagImpl[T](val mirror: Mirror, val tpec: TypeCreator) extends AbsTypeTag[T] { - lazy val tpe: Type = tpec[self.type](mirror) + lazy val tpe: Type = tpec(mirror) def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # AbsTypeTag[T] = { val otherMirror1 = otherMirror.asInstanceOf[MirrorOf[otherMirror.universe.type]] otherMirror.universe.AbsTypeTag[T](otherMirror1, tpec) diff --git a/src/library/scala/reflect/base/Types.scala b/src/library/scala/reflect/base/Types.scala index 28aaf2d04d..b016b77f36 100644 --- a/src/library/scala/reflect/base/Types.scala +++ b/src/library/scala/reflect/base/Types.scala @@ -14,7 +14,7 @@ trait Types { self: Universe => /** A tag that preserves the identity of the `Type` abstract type from erasure. * Can be used for pattern matching, instance tests, serialization and likes. */ - implicit val TypeTagg: ClassTag[Type] // [Eugene++] rename! + implicit val TypeTagg: ClassTag[Type] /** This constant is used as a special value that indicates that no meaningful type exists. */ diff --git a/src/library/scala/reflect/macros/internal/package.scala b/src/library/scala/reflect/macros/internal/package.scala index 912db53ed4..0a0e6c5b51 100644 --- a/src/library/scala/reflect/macros/internal/package.scala +++ b/src/library/scala/reflect/macros/internal/package.scala @@ -5,9 +5,7 @@ import scala.reflect.ClassTag // anchors for materialization macros emitted during tag materialization in Implicits.scala // implementation is magically hardwired into `scala.reflect.reify.Taggers` -// // todo. once we have implicit macros for tag generation, we can remove these anchors -// [Eugene++] how do I hide this from scaladoc? package object internal { private[scala] def materializeClassTag[T](u: BaseUniverse): ClassTag[T] = ??? // macro private[scala] def materializeAbsTypeTag[T](u: BaseUniverse): u.AbsTypeTag[T] = ??? // macro diff --git a/src/library/scala/util/Marshal.scala b/src/library/scala/util/Marshal.scala index 2d3f54a95e..79476bdc16 100644 --- a/src/library/scala/util/Marshal.scala +++ b/src/library/scala/util/Marshal.scala @@ -37,8 +37,6 @@ object Marshal { val in = new ObjectInputStream(new ByteArrayInputStream(buffer)) val found = in.readObject.asInstanceOf[ClassTag[_]] try { - // [Eugene] needs review - // previously was: found <:< expected found.runtimeClass.asSubclass(expected.runtimeClass) in.readObject.asInstanceOf[A] } catch { diff --git a/src/reflect/scala/reflect/api/FrontEnds.scala b/src/reflect/scala/reflect/api/FrontEnds.scala index a201b83444..a27450d49d 100644 --- a/src/reflect/scala/reflect/api/FrontEnds.scala +++ b/src/reflect/scala/reflect/api/FrontEnds.scala @@ -1,8 +1,6 @@ package scala.reflect package api -// [Martin to Eugene] Todo: Needs to be evicted from API -// [Eugene++ to Martin] but how? we need them for macros trait FrontEnds { type Position >: Null diff --git a/src/reflect/scala/reflect/api/Importers.scala b/src/reflect/scala/reflect/api/Importers.scala index de540a9605..fbc29a514e 100644 --- a/src/reflect/scala/reflect/api/Importers.scala +++ b/src/reflect/scala/reflect/api/Importers.scala @@ -1,8 +1,6 @@ package scala.reflect package api -// [Martin] Importers need to be made mirror aware. -// [Eugene++] this is important trait Importers { self: Universe => def mkImporter(from0: Universe): Importer { val from: from0.type } diff --git a/src/reflect/scala/reflect/api/JavaUniverse.scala b/src/reflect/scala/reflect/api/JavaUniverse.scala index 8bf62a357c..f2388433c4 100644 --- a/src/reflect/scala/reflect/api/JavaUniverse.scala +++ b/src/reflect/scala/reflect/api/JavaUniverse.scala @@ -1,8 +1,6 @@ package scala.reflect package api -// [Martin] Moved to compiler because it needs to see runtime.Universe -// The two will be united in scala-reflect anyway. trait JavaUniverse extends Universe with Mirrors with TagInterop { self => type RuntimeClass = java.lang.Class[_] diff --git a/src/reflect/scala/reflect/api/Mirrors.scala b/src/reflect/scala/reflect/api/Mirrors.scala index f2f96645e3..2530b20644 100644 --- a/src/reflect/scala/reflect/api/Mirrors.scala +++ b/src/reflect/scala/reflect/api/Mirrors.scala @@ -5,19 +5,7 @@ trait Mirrors { self: Universe => type RuntimeClass >: Null - // [Eugene] also, it might make sense to provide shortcuts for the API - // - // for example, right now to invoke the same method for several different instances, you need: - // 1) get the method symbol - // 2) get the instance mirror for every instance - // 3) call reflectMethod on the instance mirrors for every instance - // 4) call apply for every instance (okay, this can be united with step #3, but still) - // - // I have several suggestions that we can discuss later: - // 1) For every `reflectXXX(sym: Symbol): XXXMirror`, add `reflectXXX(name: String, types: Type*): XXXMirror` and `reflectXXXs(): List[XXXMirror]` - // 2) Provide a way to skip obtaining InstanceMirror (step #2 in the outline provided above) - - // [Eugene] another improvement would be have mirrors reproduce the structure of the reflection domain + // todo. an improvement might be having mirrors reproduce the structure of the reflection domain // e.g. a ClassMirror could also have a list of fields, methods, constructors and so on // read up more on the proposed design in "Reflecting Scala" by Y. Coppel diff --git a/src/reflect/scala/reflect/api/Positions.scala b/src/reflect/scala/reflect/api/Positions.scala index 9d3d90d9f8..5e8d958f02 100644 --- a/src/reflect/scala/reflect/api/Positions.scala +++ b/src/reflect/scala/reflect/api/Positions.scala @@ -7,6 +7,10 @@ trait Positions extends base.Positions { /** .. */ type Position >: Null <: PositionApi { type Pos = Position } + /** Assigns a given position to all position-less nodes of a given AST. + */ + def atPos[T <: Tree](pos: Position)(tree: T): T + /** A position that wraps a set of trees. * The point of the wrapping position is the point of the default position. * If some of the trees are ranges, returns a range position enclosing all ranges @@ -20,14 +24,6 @@ trait Positions extends base.Positions { * Otherwise returns a synthetic offset position to point. */ def wrappingPos(trees: List[Tree]): Position - - /** Ensure that given tree has no positions that overlap with - * any of the positions of `others`. This is done by - * shortening the range or assigning TransparentPositions - * to some of the nodes in `tree`. - */ - //def ensureNonOverlapping(tree: Tree, others: List[Tree]) - // [Eugene++] can this method be of use for macros? } /** The Position class and its subclasses represent positions of ASTs and symbols. diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala index fda76c7b95..c1221a62ab 100644 --- a/src/reflect/scala/reflect/api/Symbols.scala +++ b/src/reflect/scala/reflect/api/Symbols.scala @@ -21,7 +21,7 @@ trait Symbols extends base.Symbols { self: Universe => /** A list of annotations attached to this Symbol. */ - // [Eugene++] we cannot expose the `annotations` method because it doesn't auto-initialize a symbol (see SI-5423) + // we cannot expose the `annotations` method because it doesn't auto-initialize a symbol (see SI-5423) // there was an idea to use the `isCompilerUniverse` flag and auto-initialize symbols in `annotations` whenever this flag is false // but it doesn't work, because the unpickler (that is shared between reflective universes and global universes) is very picky about initialization // scala.reflect.internal.Types$TypeError: bad reference while unpickling scala.collection.immutable.Nil: type Nothing not found in scala.type not found. @@ -200,7 +200,6 @@ trait Symbols extends base.Symbols { self: Universe => /** The API of term symbols */ trait TermSymbolApi extends SymbolApi with TermSymbolBase { this: TermSymbol => /** Does this symbol represent a value, i.e. not a module and not a method? - * [Eugene++] I need a review of the implementation */ def isValue: Boolean diff --git a/src/reflect/scala/reflect/api/TagInterop.scala b/src/reflect/scala/reflect/api/TagInterop.scala index 4d2254cb9f..5ab085741e 100644 --- a/src/reflect/scala/reflect/api/TagInterop.scala +++ b/src/reflect/scala/reflect/api/TagInterop.scala @@ -4,16 +4,10 @@ package api import scala.reflect.base.TypeCreator import scala.reflect.base.{Universe => BaseUniverse} -// [Martin] Moved to compiler because it needs to see runtime.Universe -// The two will be united in scala-reflect anyway. trait TagInterop { self: JavaUniverse => - // [Eugene++] would be great if we could approximate the interop without any mirrors - // todo. think how to implement that - override def typeTagToManifest[T: ClassTag](mirror0: Any, tag: base.Universe # TypeTag[T]): Manifest[T] = { - // [Eugene++] implement more sophisticated logic - // Martin said it'd be okay to simply copypaste `Implicits.manifestOfType` + // SI-6239: make this conversion more precise val mirror = mirror0.asInstanceOf[Mirror] val runtimeClass = mirror.runtimeClass(tag.in(mirror).tpe) Manifest.classType(runtimeClass).asInstanceOf[Manifest[T]] diff --git a/src/reflect/scala/reflect/api/Types.scala b/src/reflect/scala/reflect/api/Types.scala index 199cf9b9e5..ebaedd7ac3 100644 --- a/src/reflect/scala/reflect/api/Types.scala +++ b/src/reflect/scala/reflect/api/Types.scala @@ -293,7 +293,6 @@ trait Types extends base.Types { self: Universe => // Creators --------------------------------------------------------------- // too useful and too non-trivial to be left out of public API - // [Eugene to Paul] needs review! /** The canonical creator for single-types */ def singleType(pre: Type, sym: Symbol): Type diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index c6815d10c3..fcbe7d0ed9 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -19,23 +19,6 @@ trait Definitions extends api.StandardDefinitions { object definitions extends DefinitionsClass - // [Eugene] find a way to make these non-lazy - lazy val ByteTpe = definitions.ByteClass.toTypeConstructor - lazy val ShortTpe = definitions.ShortClass.toTypeConstructor - lazy val CharTpe = definitions.CharClass.toTypeConstructor - lazy val IntTpe = definitions.IntClass.toTypeConstructor - lazy val LongTpe = definitions.LongClass.toTypeConstructor - lazy val FloatTpe = definitions.FloatClass.toTypeConstructor - lazy val DoubleTpe = definitions.DoubleClass.toTypeConstructor - lazy val BooleanTpe = definitions.BooleanClass.toTypeConstructor - lazy val UnitTpe = definitions.UnitClass.toTypeConstructor - lazy val AnyTpe = definitions.AnyClass.toTypeConstructor - lazy val ObjectTpe = definitions.ObjectClass.toTypeConstructor - lazy val AnyValTpe = definitions.AnyValClass.toTypeConstructor - lazy val AnyRefTpe = definitions.AnyRefClass.toTypeConstructor - lazy val NothingTpe = definitions.NothingClass.toTypeConstructor - lazy val NullTpe = definitions.NullClass.toTypeConstructor - /** Since both the value parameter types and the result type may * require access to the type parameter symbols, we model polymorphic * creation as a function from those symbols to (formal types, result type). @@ -143,6 +126,16 @@ trait Definitions extends api.StandardDefinitions { lazy val Boolean_or = getMemberMethod(BooleanClass, nme.ZOR) lazy val Boolean_not = getMemberMethod(BooleanClass, nme.UNARY_!) + lazy val UnitTpe = UnitClass.toTypeConstructor + lazy val ByteTpe = ByteClass.toTypeConstructor + lazy val ShortTpe = ShortClass.toTypeConstructor + lazy val CharTpe = CharClass.toTypeConstructor + lazy val IntTpe = IntClass.toTypeConstructor + lazy val LongTpe = LongClass.toTypeConstructor + lazy val FloatTpe = FloatClass.toTypeConstructor + lazy val DoubleTpe = DoubleClass.toTypeConstructor + lazy val BooleanTpe = BooleanClass.toTypeConstructor + lazy val ScalaNumericValueClasses = ScalaValueClasses filterNot Set[Symbol](UnitClass, BooleanClass) def ScalaValueClassesNoUnit = ScalaValueClasses filterNot (_ eq UnitClass) @@ -242,6 +235,9 @@ trait Definitions extends api.StandardDefinitions { lazy val AnyClass = enterNewClass(ScalaPackageClass, tpnme.Any, Nil, ABSTRACT) lazy val AnyRefClass = newAlias(ScalaPackageClass, tpnme.AnyRef, ObjectClass.tpe) lazy val ObjectClass = getRequiredClass(sn.Object.toString) + lazy val AnyTpe = definitions.AnyClass.toTypeConstructor + lazy val AnyRefTpe = definitions.AnyRefClass.toTypeConstructor + lazy val ObjectTpe = definitions.ObjectClass.toTypeConstructor // Note: this is not the type alias AnyRef, it's a companion-like // object used by the @specialize annotation. @@ -255,6 +251,7 @@ trait Definitions extends api.StandardDefinitions { anyval.info.decls enter av_constr anyval }).asInstanceOf[ClassSymbol] + lazy val AnyValTpe = definitions.AnyValClass.toTypeConstructor // bottom types lazy val RuntimeNothingClass = getClassByName(fulltpnme.RuntimeNothing) @@ -276,6 +273,8 @@ trait Definitions extends api.StandardDefinitions { || (that ne NothingClass) && (that isSubClass ObjectClass) ) } + lazy val NothingTpe = definitions.NothingClass.toTypeConstructor + lazy val NullTpe = definitions.NullClass.toTypeConstructor // exceptions and other throwables lazy val ClassCastExceptionClass = requiredClass[ClassCastException] @@ -302,7 +301,7 @@ trait Definitions extends api.StandardDefinitions { def Sys_error = getMemberMethod(SysPackage, nme.error) // Modules whose members are in the default namespace - // [Eugene++] ScalaPackage and JavaLangPackage are never ever shared between mirrors + // SI-5941: ScalaPackage and JavaLangPackage are never ever shared between mirrors // as a result, `Int` becomes `scala.Int` and `String` becomes `java.lang.String` // I could just change `isOmittablePrefix`, but there's more to it, so I'm leaving this as a todo for now lazy val UnqualifiedModules = List(PredefModule, ScalaPackage, JavaLangPackage) @@ -338,7 +337,6 @@ trait Definitions extends api.StandardDefinitions { lazy val SymbolModule = requiredModule[scala.Symbol.type] lazy val Symbol_apply = getMemberMethod(SymbolModule, nme.apply) - def SeqFactory = getMember(ScalaRunTimeModule, nme.Seq) // [Eugene++] obsolete? def arrayApplyMethod = getMemberMethod(ScalaRunTimeModule, nme.array_apply) def arrayUpdateMethod = getMemberMethod(ScalaRunTimeModule, nme.array_update) def arrayLengthMethod = getMemberMethod(ScalaRunTimeModule, nme.array_length) @@ -978,12 +976,7 @@ trait Definitions extends api.StandardDefinitions { throw new FatalError(owner + " does not have a " + what + " " + name) } - def getLanguageFeature(name: String, owner: Symbol = languageFeatureModule): Symbol = - // [Eugene++] `getMemberClass` leads to crashes in mixin: - // "object languageFeature does not have a member class implicitConversions" - // that's because by that time `implicitConversions` becomes a module - // getMemberClass(owner, newTypeName(name)) - getMember(owner, newTypeName(name)) + def getLanguageFeature(name: String, owner: Symbol = languageFeatureModule): Symbol = getMember(owner, newTypeName(name)) def termMember(owner: Symbol, name: String): Symbol = owner.info.member(newTermName(name)) def typeMember(owner: Symbol, name: String): Symbol = owner.info.member(newTypeName(name)) @@ -1008,28 +1001,24 @@ trait Definitions extends api.StandardDefinitions { } } def getMemberValue(owner: Symbol, name: Name): TermSymbol = { - // [Eugene++] should be a ClassCastException instead? getMember(owner, name.toTermName) match { case x: TermSymbol => x case _ => fatalMissingSymbol(owner, name, "member value") } } def getMemberModule(owner: Symbol, name: Name): ModuleSymbol = { - // [Eugene++] should be a ClassCastException instead? getMember(owner, name.toTermName) match { case x: ModuleSymbol => x case _ => fatalMissingSymbol(owner, name, "member object") } } def getMemberType(owner: Symbol, name: Name): TypeSymbol = { - // [Eugene++] should be a ClassCastException instead? getMember(owner, name.toTypeName) match { case x: TypeSymbol => x case _ => fatalMissingSymbol(owner, name, "member type") } } def getMemberClass(owner: Symbol, name: Name): ClassSymbol = { - // [Eugene++] should be a ClassCastException instead? val y = getMember(owner, name.toTypeName) getMember(owner, name.toTypeName) match { case x: ClassSymbol => x @@ -1037,48 +1026,8 @@ trait Definitions extends api.StandardDefinitions { } } def getMemberMethod(owner: Symbol, name: Name): TermSymbol = { - // [Eugene++] is this a bug? - // - // System.err.println(result.getClass) - // System.err.println(result.flags) - // System.err.println("isMethod = " + result.isMethod) - // System.err.println("isTerm = " + result.isTerm) - // System.err.println("isValue = " + result.isValue) - // result.asMethod - // - // prints this: - // - // quick.lib: - // [javac] Compiling 1 source file to C:\Projects\KeplerUnderRefactoring\build\quick\classes\library - // [scalacfork] Compiling 769 files to C:\Projects\KeplerUnderRefactoring\build\quick\classes\library - // [scalacfork] class scala.reflect.internal.Symbols$TermSymbol - // [scalacfork] 8589934592 - // [scalacfork] isMethod = false - // [scalacfork] isTerm = true - // [scalacfork] isValue = true - // [scalacfork] - // [scalacfork] while compiling: C:\Projects\KeplerUnderRefactoring\src\library\scala\LowPriorityImplicits.scala - // [scalacfork] current phase: cleanup - // [scalacfork] library version: version 2.10.0-20120507-185519-665d1d9127 - // [scalacfork] compiler version: version 2.10.0-20120507-185519-665d1d9127 - // [scalacfork] reconstructed args: -Xmacros -classpath C:\\Projects\\KeplerUnderRefactoring\\build\\quick\\classes\\library;C:\\Projects\\KeplerUnderRefactoring\\lib\\forkjoin.jar -d C:\\Projects\\KeplerUnderRefactoring\\build\\quick\\classes\\library -sourcepath C:\\Projects\\KeplerUnderRefactoring\\src\\library - // [scalacfork] - // [scalacfork] unhandled exception while transforming LowPriorityImplicits.scala - // [scalacfork] error: - // [scalacfork] while compiling: C:\Projects\KeplerUnderRefactoring\src\library\scala\LowPriorityImplicits.scala - // [scalacfork] current phase: cleanup - // [scalacfork] library version: version 2.10.0-20120507-185519-665d1d9127 - // [scalacfork] compiler version: version 2.10.0-20120507-185519-665d1d9127 - // [scalacfork] reconstructed args: -Xmacros -classpath C:\\Projects\\KeplerUnderRefactoring\\build\\quick\\classes\\library;C:\\Projects\\KeplerUnderRefactoring\\lib\\forkjoin.jar -d C:\\Projects\\KeplerUnderRefactoring\\build\\quick\\classes\\library -sourcepath C:\\Projects\\KeplerUnderRefactoring\\src\\library - // [scalacfork] - // [scalacfork] uncaught exception during compilation: java.lang.ClassCastException - // [scalacfork] error: java.lang.ClassCastException: value apply - // [scalacfork] at scala.reflect.base.Symbols$SymbolBase$class.asMethod(Symbols.scala:118) - // [scalacfork] at scala.reflect.internal.Symbols$SymbolContextApiImpl.asMethod(Symbols.scala:63) - // [scalacfork] at scala.reflect.internal.Definitions$DefinitionsClass.Symbol_apply(Definitions.scala:381) - - // [Eugene++] should be a ClassCastException instead? getMember(owner, name.toTermName) match { + // todo. member symbol becomes a term symbol in cleanup. is this a bug? // case x: MethodSymbol => x case x: TermSymbol => x case _ => fatalMissingSymbol(owner, name, "method") diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala index 00017e087a..25441f9812 100644 --- a/src/reflect/scala/reflect/internal/Importers.scala +++ b/src/reflect/scala/reflect/internal/Importers.scala @@ -2,10 +2,9 @@ package scala.reflect package internal import scala.collection.mutable.WeakHashMap -// todo: move importers to a mirror +// SI-6241: move importers to a mirror trait Importers { self: SymbolTable => - // [Eugene] possible to make this less cast-heavy? def mkImporter(from0: api.Universe): Importer { val from: from0.type } = ( if (self eq from0) { new Importer { diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala index 0c86e4fba0..9580ed1f72 100644 --- a/src/reflect/scala/reflect/internal/Printers.scala +++ b/src/reflect/scala/reflect/internal/Printers.scala @@ -3,7 +3,7 @@ * @author Martin Odersky */ -// [Eugene++ to Martin] we need to unify this prettyprinter with NodePrinters +// todo. we need to unify this prettyprinter with NodePrinters package scala.reflect package internal @@ -174,12 +174,7 @@ trait Printers extends api.Printers { self: SymbolTable => } def printAnnotations(tree: Tree) { - if (!isCompilerUniverse && tree.symbol != null && tree.symbol != NoSymbol) - // [Eugene++] todo. this is not 100% correct, but is necessary for sane printing - // the problem is that getting annotations doesn't automatically initialize the symbol - // so we might easily print something as if it doesn't have annotations, whereas it does - tree.symbol.initialize - + // SI-5885: by default this won't print annotations of not yet initialized symbols val annots = tree.symbol.annotations match { case Nil => tree.asInstanceOf[MemberDef].mods.annotations case anns => anns diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index c1e5f78d50..f63e2602b1 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -1008,8 +1008,6 @@ trait StdNames { val javanme = nme.javaKeywords - // [Eugene++ to Martin] had to move a lot of stuff from here to TermNames to satisfy the contract - // why do we even have stuff in object nme? cf. object tpnme object nme extends TermNames { def isModuleVarName(name: Name): Boolean = diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index ac8b254f83..4dd40c8a4f 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -839,7 +839,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def isInitialized: Boolean = validTo != NoPeriod - // [Eugene] todo. needs to be reviewed and [only then] rewritten without explicit returns /** Determines whether this symbol can be loaded by subsequent reflective compilation */ final def isLocatable: Boolean = { if (this == NoSymbol) return false diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index 94d51b7455..3894870252 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -979,12 +979,7 @@ trait Trees extends api.Trees { self: SymbolTable => */ def New(tpt: Tree, argss: List[List[Tree]]): Tree = argss match { case Nil => ApplyConstructor(tpt, Nil) - case xs :: rest => { - def mkApply(fun: Tree, args: List[Tree]) = Apply(fun, args) - rest.foldLeft(ApplyConstructor(tpt, xs): Tree)(mkApply) - // [Eugene++] no longer compiles after I moved the `Apply` case class here - // rest.foldLeft(ApplyConstructor(tpt, xs): Tree)(Apply) - } + case xs :: rest => rest.foldLeft(ApplyConstructor(tpt, xs): Tree)(Apply.apply) } /** 0-1 argument list new, based on a type. diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index b6305e773a..56506246ca 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -265,14 +265,14 @@ trait Types extends api.Types { self: SymbolTable => def declarations = decls def typeArguments = typeArgs def erasure = this match { - case ConstantType(value) => widen.erasure // [Eugene to Martin] constant types are unaffected by erasure. weird. + case ConstantType(value) => widen.erasure case _ => var result: Type = transformedType(this) result = result.normalize match { // necessary to deal with erasures of HK types, typeConstructor won't work case PolyType(undets, underlying) => existentialAbstraction(undets, underlying) // we don't want undets in the result case _ => result } - // [Eugene] erasure screws up all ThisTypes for modules into PackageTypeRefs + // erasure screws up all ThisTypes for modules into PackageTypeRefs // we need to unscrew them, or certain typechecks will fail mysteriously // http://groups.google.com/group/scala-internals/browse_thread/thread/6d3277ae21b6d581 result = result.map(tpe => tpe match { @@ -284,7 +284,6 @@ trait Types extends api.Types { self: SymbolTable => def substituteSymbols(from: List[Symbol], to: List[Symbol]): Type = substSym(from, to) def substituteTypes(from: List[Symbol], to: List[Type]): Type = subst(from, to) - // [Eugene] to be discussed and refactored def isConcrete = { def notConcreteSym(sym: Symbol) = sym.isAbstractType && !sym.isExistential @@ -304,11 +303,8 @@ trait Types extends api.Types { self: SymbolTable => !notConcreteTpe(this) } - // [Eugene] is this comprehensive? - // the only thingies that we want to splice are: 1) type parameters, 2) type members + // the only thingies that we want to splice are: 1) type parameters, 2) abstract type members // the thingies that we don't want to splice are: 1) concrete types (obviously), 2) existential skolems - // this check seems to cover them all, right? - // todo. after we discuss this, move the check to subclasses def isSpliceable = { this.isInstanceOf[TypeRef] && typeSymbol.isAbstractType && !typeSymbol.isExistential } diff --git a/src/reflect/scala/reflect/macros/Infrastructure.scala b/src/reflect/scala/reflect/macros/Infrastructure.scala index 5ae2c08265..a8a8b814b1 100644 --- a/src/reflect/scala/reflect/macros/Infrastructure.scala +++ b/src/reflect/scala/reflect/macros/Infrastructure.scala @@ -46,10 +46,6 @@ trait Infrastructure { * val valueOfX = toolBox.runExpr(imported).asInstanceOf[T] * ... * } - * - * // [Eugene++] using this guy will tremendously slow down the compilation - * // https://twitter.com/xeno_by/status/201248317831774208 - * // todo. we need to address this somehow */ def libraryClassLoader: ClassLoader diff --git a/src/reflect/scala/reflect/macros/Settings.scala b/src/reflect/scala/reflect/macros/Settings.scala index 8d166056c3..a2cdb4c8e1 100644 --- a/src/reflect/scala/reflect/macros/Settings.scala +++ b/src/reflect/scala/reflect/macros/Settings.scala @@ -12,14 +12,10 @@ trait Settings { /** Exposes current compiler settings as a list of options. * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options. */ - // [Eugene] ugly? yes, but I don't really fancy copy/pasting all our settings here and keep it synchronized at all times - // why all settings? because macros need to be in full control of the stuff going on - // maybe later we can implement a gettable/settable list of important settings, but for now let's leave it like that def compilerSettings: List[String] /** Updates current compiler settings with an option string. * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options. - * todo. http://groups.google.com/group/scala-internals/browse_thread/thread/07c18cff41f59203 */ def setCompilerSettings(options: String): this.type @@ -28,12 +24,12 @@ trait Settings { */ def setCompilerSettings(options: List[String]): this.type - /** Temporary sets compiler settings to a given option string and executes a given closure. + /** Temporarily sets compiler settings to a given option string and executes a given closure. * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options. */ def withCompilerSettings[T](options: String)(op: => T): T - /** Temporary sets compiler settings to a given list of options and executes a given closure. + /** Temporarily sets compiler settings to a given list of options and executes a given closure. * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options. */ def withCompilerSettings[T](options: List[String])(op: => T): T diff --git a/src/reflect/scala/reflect/macros/TreeBuilder.scala b/src/reflect/scala/reflect/macros/TreeBuilder.scala index 06f5caf68b..ca29194859 100644 --- a/src/reflect/scala/reflect/macros/TreeBuilder.scala +++ b/src/reflect/scala/reflect/macros/TreeBuilder.scala @@ -1,10 +1,6 @@ package scala.reflect package macros -// [Eugene] I added some stuff that was necessary for typetag materialization macros -// but we should think it over and pick other generally useful stuff -// same goes for tree traversers/transformers, type maps, etc -// and once we expose all that, there's another question: how do we stay in sync? abstract class TreeBuilder { val global: Universe diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index 4ce2cda04a..967ac69148 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -88,7 +88,6 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym // ----------- Caching ------------------------------------------------------------------ - // [Eugene++ to Martin] not weak? why? private val classCache = new TwoWayCache[jClass[_], ClassSymbol] private val packageCache = new TwoWayCache[Package, ModuleSymbol] private val methodCache = new TwoWayCache[jMethod, MethodSymbol] @@ -659,43 +658,33 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym private def followStatic(clazz: Symbol, mods: Int) = if (jModifier.isStatic(mods)) clazz.companionModule.moduleClass else clazz - implicit class RichClass(jclazz: jClass[_]) { - // [Eugene++] `jclazz.isLocalClass` doesn't work because of problems with `getSimpleName` - // java.lang.Error: sOwner(class Test$A$1) has failed - // Caused by: java.lang.InternalError: Malformed class name - // at java.lang.Class.getSimpleName(Class.java:1133) - // at java.lang.Class.isAnonymousClass(Class.java:1188) - // at java.lang.Class.isLocalClass(Class.java:1199) - // (see t5256c.scala for more details) + /** Methods which need to be treated with care + * because they either are getSimpleName or call getSimpleName: + * + * public String getSimpleName() + * public boolean isAnonymousClass() + * public boolean isLocalClass() + * public String getCanonicalName() + * + * A typical manifestation: + * + * // java.lang.Error: sOwner(class Test$A$1) has failed + * // Caused by: java.lang.InternalError: Malformed class name + * // at java.lang.Class.getSimpleName(Class.java:1133) + * // at java.lang.Class.isAnonymousClass(Class.java:1188) + * // at java.lang.Class.isLocalClass(Class.java:1199) + * // (see t5256c.scala for more details) + * + * TODO - find all such calls and wrap them. + * TODO - create mechanism to avoid the recurrence of unwrapped calls. + */ + implicit class RichClass(jclazz: jClass[_]) { + // `jclazz.isLocalClass` doesn't work because of problems with `getSimpleName` // hence we have to approximate by removing the `isAnonymousClass` check // def isLocalClass0: Boolean = jclazz.isLocalClass def isLocalClass0: Boolean = jclazz.getEnclosingMethod != null || jclazz.getEnclosingConstructor != null } - // [Eugene++] overflow from Paul's changes made concurrently with reflection refactoring - // https://github.com/scala/scala/commit/90d2bee45b25844f809f8c5300aefcb1bfe9e336 - // - // /** Methods which need to be wrapped because they either are getSimpleName - // * or call getSimpleName: - // * - // * public String getSimpleName() - // * public boolean isAnonymousClass() - // * public boolean isLocalClass() - // * public boolean isMemberClass() - // * public String getCanonicalName() - // * - // * TODO - find all such calls and wrap them. - // * TODO - create mechanism to avoid the recurrence of unwrapped calls. - // */ - // private def wrapClassCheck[T](alt: T)(body: => T): T = - // try body catch { case x: InternalError if x.getMessage == "Malformed class name" => alt } - - // private def wrapIsLocalClass(clazz: jClass[_]): Boolean = - // wrapClassCheck(false)(clazz.isLocalClass) - - // private def wrapGetSimpleName(clazz: jClass[_]): String = - // wrapClassCheck("")(clazz.getSimpleName) - /** * The Scala owner of the Scala class corresponding to the Java class `jclazz` */ @@ -1208,7 +1197,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym override def missingHook(owner: Symbol, name: Name): Symbol = { if (owner.hasPackageFlag) { val mirror = mirrorThatLoaded(owner) - // [Eugene++] this makes toolbox tests pass, but it's a mere workaround for SI-5865 + // todo. this makes toolbox tests pass, but it's a mere workaround for SI-5865 // assert((owner.info decl name) == NoSymbol, s"already exists: $owner . $name") if (owner.isRootSymbol && mirror.tryJavaClass(name.toString).isDefined) return mirror.EmptyPackageClass.info decl name diff --git a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala index eb48e9dc79..583b9d93f3 100644 --- a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala +++ b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala @@ -61,10 +61,8 @@ trait SymbolLoaders { self: SymbolTable => assert(!(name.toString endsWith "[]"), name) val clazz = owner.newClass(name) val module = owner.newModule(name.toTermName) - // [Eugene++] am I doing this right? - // todo: drop condition, see what goes wrong - // [Eugene++ to Martin] test/files/run/t5256g and test/files/run/t5256h will crash - // reflection meeting verdict: need to enter the symbols into the first symbol in the owner chain that has a non-empty scope + // without this check test/files/run/t5256g and test/files/run/t5256h will crash + // todo. reflection meeting verdict: need to enter the symbols into the first symbol in the owner chain that has a non-empty scope if (owner.info.decls != EmptyScope) { owner.info.decls enter clazz owner.info.decls enter module diff --git a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala index 907c0dd369..1a17dd12d2 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala @@ -1,6 +1,7 @@ package scala.reflect package runtime +// SI-6240: test thread-safety, make trees synchronized as well trait SynchronizedOps extends internal.SymbolTable with SynchronizedSymbols with SynchronizedTypes { self: SymbolTable => diff --git a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala index c65357b652..12db7a7bf9 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala @@ -134,8 +134,6 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable => trait SynchronizedModuleClassSymbol extends ModuleClassSymbol with SynchronizedClassSymbol { override def sourceModule = synchronized { super.sourceModule } - // [Eugene++ to Martin] doesn't override anything. no longer necessary? - // def sourceModule_=(module: ModuleSymbol) = synchronized { super.sourceModule_=(module) } override def implicitMembers: Scope = synchronized { super.implicitMembers } } } diff --git a/src/reflect/scala/reflect/runtime/package.scala b/src/reflect/scala/reflect/runtime/package.scala index d00094c0c1..ccdea3e82d 100644 --- a/src/reflect/scala/reflect/runtime/package.scala +++ b/src/reflect/scala/reflect/runtime/package.scala @@ -5,8 +5,6 @@ package object runtime { // type is api.JavaUniverse because we only want to expose the `scala.reflect.api.*` subset of reflection lazy val universe: api.JavaUniverse = new runtime.JavaUniverse - // [Eugene++ to Martin] removed `mirrorOfLoader`, because one can use `universe.runtimeMirror` instead - // implementation magically hardwired to the `currentMirror` method below def currentMirror: universe.Mirror = ??? // macro } diff --git a/src/reflect/scala/tools/nsc/io/Path.scala b/src/reflect/scala/tools/nsc/io/Path.scala index bfad4b93c5..e965c70111 100644 --- a/src/reflect/scala/tools/nsc/io/Path.scala +++ b/src/reflect/scala/tools/nsc/io/Path.scala @@ -43,8 +43,6 @@ object Path { if (i < 0) "" else name.substring(i + 1).toLowerCase } - // [Eugene++] I hope that noone relied on this method -// def isJarOrZip(f: Path, examineFile: Boolean = true) = Jar.isJarOrZip(f, examineFile) // not certain these won't be problematic, but looks good so far implicit def string2path(s: String): Path = apply(s) diff --git a/test/files/run/reify_ann1a.scala b/test/files/run/reify_ann1a.scala index 9f994fb2eb..754baef6b7 100644 --- a/test/files/run/reify_ann1a.scala +++ b/test/files/run/reify_ann1a.scala @@ -21,6 +21,7 @@ object Test extends App { // test 2: import and typecheck val toolbox = cm.mkToolBox() val ttree = toolbox.typeCheck(tree) + ttree.foreach(sub => if (sub.hasSymbol) sub.symbol.typeSignature) println(ttree.toString) // test 3: import and compile diff --git a/test/files/run/reify_ann1b.scala b/test/files/run/reify_ann1b.scala index 3e0d3e0802..eb00b4cb10 100644 --- a/test/files/run/reify_ann1b.scala +++ b/test/files/run/reify_ann1b.scala @@ -21,6 +21,7 @@ object Test extends App { // test 2: import and typecheck val toolbox = cm.mkToolBox() val ttree = toolbox.typeCheck(tree) + ttree.foreach(sub => if (sub.hasSymbol) sub.symbol.typeSignature) println(ttree.toString) // test 3: import and compile diff --git a/test/files/run/reify_ann2a.scala b/test/files/run/reify_ann2a.scala index 63a17ee192..9f901d86bd 100644 --- a/test/files/run/reify_ann2a.scala +++ b/test/files/run/reify_ann2a.scala @@ -21,6 +21,7 @@ object Test extends App { // test 2: import and typecheck val toolbox = cm.mkToolBox() val ttree = toolbox.typeCheck(tree) + ttree.foreach(sub => if (sub.hasSymbol) sub.symbol.typeSignature) println(ttree.toString) // test 3: import and compile diff --git a/test/files/run/reify_ann3.scala b/test/files/run/reify_ann3.scala index dbb6a1b443..cbf1e10063 100644 --- a/test/files/run/reify_ann3.scala +++ b/test/files/run/reify_ann3.scala @@ -15,6 +15,7 @@ object Test extends App { // test 2: import and typecheck val toolbox = cm.mkToolBox() val ttree = toolbox.typeCheck(tree) + ttree.foreach(sub => if (sub.hasSymbol) sub.symbol.typeSignature) println(ttree.toString) // test 3: import and compile diff --git a/test/files/run/reify_ann4.scala b/test/files/run/reify_ann4.scala index b4845d1586..58c8c2c521 100644 --- a/test/files/run/reify_ann4.scala +++ b/test/files/run/reify_ann4.scala @@ -19,6 +19,7 @@ object Test extends App { // test 2: import and typecheck val toolbox = cm.mkToolBox() val ttree = toolbox.typeCheck(tree) + ttree.foreach(sub => if (sub.hasSymbol) sub.symbol.typeSignature) println(ttree.toString) // test 3: import and compile diff --git a/test/files/run/reify_ann5.scala b/test/files/run/reify_ann5.scala index 0ae8d317ce..801db07960 100644 --- a/test/files/run/reify_ann5.scala +++ b/test/files/run/reify_ann5.scala @@ -16,6 +16,7 @@ object Test extends App { // test 2: import and typecheck val toolbox = cm.mkToolBox() val ttree = toolbox.typeCheck(tree) + ttree.foreach(sub => if (sub.hasSymbol) sub.symbol.typeSignature) println(ttree.toString) // test 3: import and compile -- cgit v1.2.3 From 8ca3cdb569789ab360336a8e498b815fa0097f94 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Wed, 15 Aug 2012 14:21:37 +0200 Subject: materializeImplicit and implicitsOfExpectedType Previously these guys were coupled in a single method. Now they are separated. In my opinion that helps understanding the stuff going on in implicit search. --- .../scala/tools/nsc/typechecker/Implicits.scala | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 924d590edb..a34fc71b8f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -1337,13 +1337,7 @@ trait Implicits { /** Materializes implicits of magic types (currently, manifests and tags). * Will be replaced by implicit macros once we fix them. */ - private def materializeImplicit(pt: Type): SearchResult = { - def fallback = { - searchImplicit(implicitsOfExpectedType, false) - // shouldn't we pass `pt` to `implicitsOfExpectedType`, or is the recursive case - // for an abstract type really only meant for tags? - } - + private def materializeImplicit(pt: Type): SearchResult = pt match { case TypeRef(_, sym, _) if sym.isAbstractType => materializeImplicit(pt.dealias.bounds.lo) // #3977: use pt.dealias, not pt (if pt is a type alias, pt.bounds.lo == pt) @@ -1359,12 +1353,11 @@ trait Implicits { // unlike `dealias`, `betaReduce` performs at most one step of dealiasing // while dealias pops all aliases in a single invocation case sym if sym.isAliasType => materializeImplicit(pt.betaReduce) - case _ => fallback + case _ => SearchFailure } case _ => - fallback + SearchFailure } - } /** The result of the implicit search: * First search implicits visible in current context. @@ -1397,6 +1390,10 @@ trait Implicits { result = materializeImplicit(pt) + // `materializeImplicit` does some preprocessing for `pt` + // is it only meant for manifests/tags or we need to do the same for `implicitsOfExpectedType`? + if (result == SearchFailure) result = searchImplicit(implicitsOfExpectedType, false) + if (result == SearchFailure) { context.updateBuffer(previousErrs) Statistics.stopTimer(oftypeFailNanos, failstart) -- cgit v1.2.3 From 6a67ef69144e5ad33857fde582cbf191e56cd82b Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Wed, 15 Aug 2012 15:35:02 +0200 Subject: phaseId(currentPeriod) >= erasurePhase.id Simplifies this expression found in Typers to just phase.erasedTypes. --- src/compiler/scala/tools/nsc/typechecker/Typers.scala | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 7c509f4d33..9b07eed5d7 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -5180,9 +5180,7 @@ trait Typers extends Modes with Adaptations with Tags { case ReferenceToBoxed(idt @ Ident(_)) => val id1 = typed1(idt, mode, pt) match { case id: Ident => id } - // [Eugene] am I doing it right? - val erasedTypes = phaseId(currentPeriod) >= currentRun.erasurePhase.id - val tpe = capturedVariableType(idt.symbol, erasedTypes = erasedTypes) + val tpe = capturedVariableType(idt.symbol, erasedTypes = phase.erasedTypes) treeCopy.ReferenceToBoxed(tree, id1) setType tpe case Literal(value) => -- cgit v1.2.3 From 19659ba878605cf5b6d9cbd3ba9ced812336817f Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Wed, 15 Aug 2012 15:39:41 +0200 Subject: Dominik's comments on api.Mirrors --- src/reflect/scala/reflect/api/Mirrors.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/reflect/scala/reflect/api/Mirrors.scala b/src/reflect/scala/reflect/api/Mirrors.scala index 2530b20644..7d185d9879 100644 --- a/src/reflect/scala/reflect/api/Mirrors.scala +++ b/src/reflect/scala/reflect/api/Mirrors.scala @@ -150,7 +150,7 @@ trait Mirrors { self: Universe => def runtimeClass: RuntimeClass /** True if the mirror represents the static part - * if a runtime class or the companion object of a Scala class. + * of a runtime class or the companion object of a Scala class. * One has: * * this.isStatic == this.isInstanceOf[ModuleMirror] @@ -192,7 +192,7 @@ trait Mirrors { self: Universe => * Otherwise, if the mirror represents the static part of a runtime class, the * mirror representing the instance part of the same class. */ - def companion: Option[ClassMirror] + override def companion: Option[ClassMirror] } /** A mirror that reflects the instance parts of a runtime class */ @@ -219,7 +219,7 @@ trait Mirrors { self: Universe => * Otherwise, if the mirror represents a runtime instance class, a mirror representing the static * part of the same class. */ - def companion: Option[ModuleMirror] + override def companion: Option[ModuleMirror] } /** A mirror that reflects instances and static classes */ -- cgit v1.2.3 From 414106d32c1646f1e2f86040804555fedbbb667d Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Wed, 15 Aug 2012 16:11:26 +0200 Subject: macroImplSigs => macroImplSig We no longer have multiple canonical signatures for macro implementations, so it was time to put the List-List-List-based logic to rest. --- .../scala/tools/nsc/typechecker/Macros.scala | 58 ++++++---------------- .../neg/macro-invalidsig-params-namemismatch.check | 1 + 2 files changed, 15 insertions(+), 44 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index c2ab5edbb6..ab2221a6c4 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -212,7 +212,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { MacroImplBinding.unpickle(pickle) } - /** A list of compatible macro implementation signatures. + /** A reference macro implementation signature compatible with a given macro definition. * * In the example above: * (c: scala.reflect.macros.Context)(xs: c.Expr[List[T]]): c.Expr[T] @@ -222,7 +222,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { * @param vparamss The value parameters of the macro definition * @param retTpe The return type of the macro definition */ - private def macroImplSigs(macroDef: Symbol, tparams: List[TypeDef], vparamss: List[List[ValDef]], retTpe: Type): (List[List[List[Symbol]]], Type) = { + private def macroImplSig(macroDef: Symbol, tparams: List[TypeDef], vparamss: List[List[ValDef]], retTpe: Type): (List[List[Symbol]], Type) = { // had to move method's body to an object because of the recursive dependencies between sigma and param object SigGenerator { val hasThis = macroDef.owner.isClass @@ -287,17 +287,8 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { val paramsThis = List(makeParam(nme.macroThis, macroDef.pos, implType(false, ownerTpe), SYNTHETIC)) val paramsTparams = tparams map param val paramssParams = mmap(vparamss)(param) - - var paramsss = List[List[List[Symbol]]]() - // tparams are no longer part of a signature, they get into macro implementations via context bounds -// if (hasTparams && hasThis) paramsss :+= paramsCtx :: paramsThis :: paramsTparams :: paramssParams -// if (hasTparams) paramsss :+= paramsCtx :: paramsTparams :: paramssParams - // _this params are no longer part of a signature, its gets into macro implementations via Context.prefix -// if (hasThis) paramsss :+= paramsCtx :: paramsThis :: paramssParams - paramsss :+= paramsCtx :: paramssParams - - val tsym = getMember(MacroContextClass, tpnme.Expr) - val implRetTpe = typeRef(singleType(NoPrefix, ctxParam), tsym, List(sigma(retTpe))) + val paramss = paramsCtx :: paramssParams + val implRetTpe = typeRef(singleType(NoPrefix, ctxParam), getMember(MacroContextClass, tpnme.Expr), List(sigma(retTpe))) } import SigGenerator._ @@ -305,7 +296,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { macroTraceVerbose("tparams are: ")(tparams) macroTraceVerbose("vparamss are: ")(vparamss) macroTraceVerbose("retTpe is: ")(retTpe) - macroTraceVerbose("macroImplSigs are: ")(paramsss, implRetTpe) + macroTraceVerbose("macroImplSig is: ")(paramss, implRetTpe) } private def transformTypeTagEvidenceParams(paramss: List[List[Symbol]], transform: (Symbol, Symbol) => Symbol): List[List[Symbol]] = { @@ -375,7 +366,6 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { def reportError(pos: Position, msg: String) = { setError() context.error(pos, msg) - macroDef setFlag IS_ERROR } def invalidBodyError() = @@ -596,22 +586,19 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { var actparamss = macroImpl.paramss actparamss = transformTypeTagEvidenceParams(actparamss, (param, tparam) => NoSymbol) - - val rettpe = if (!ddef.tpt.isEmpty) typer.typedType(ddef.tpt).tpe else computeMacroDefTypeFromMacroImpl(ddef, macroDef, macroImpl) - val (reqparamsss0, reqres0) = macroImplSigs(macroDef, ddef.tparams, ddef.vparamss, rettpe) - var reqparamsss = reqparamsss0 - - // prohibit implicit params on macro implementations - // we don't have to do this, but it appears to be more clear than allowing them + val actres = macroImpl.tpe.finalResultType val implicitParams = actparamss.flatten filter (_.isImplicit) if (implicitParams.length > 0) { + // prohibit implicit params on macro implementations + // we don't have to do this, but it appears to be more clear than allowing them reportError(implicitParams.head.pos, "macro implementations cannot have implicit parameters other than AbsTypeTag evidences") macroTraceVerbose("macro def failed to satisfy trivial preconditions: ")(macroDef) } if (!hasError) { - val reqres = reqres0 - val actres = macroImpl.tpe.finalResultType + val rettpe = if (!ddef.tpt.isEmpty) typer.typedType(ddef.tpt).tpe else computeMacroDefTypeFromMacroImpl(ddef, macroDef, macroImpl) + val (reqparamss, reqres) = macroImplSig(macroDef, ddef.tparams, ddef.vparamss, rettpe) + def showMeth(pss: List[List[Symbol]], restpe: Type, abbreviate: Boolean) = { var argsPart = (pss map (ps => ps map (_.defString) mkString ("(", ", ", ")"))).mkString if (abbreviate) argsPart = argsPart.abbreviateCoreAliases @@ -622,29 +609,12 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { def compatibilityError(addendum: String) = reportError(implpos, "macro implementation has wrong shape:"+ - "\n required: "+showMeth(reqparamsss.head, reqres, true) + - (reqparamsss.tail map (paramss => "\n or : "+showMeth(paramss, reqres, true)) mkString "")+ + "\n required: "+showMeth(reqparamss, reqres, true) + "\n found : "+showMeth(actparamss, actres, false)+ "\n"+addendum) - macroTraceVerbose("considering " + reqparamsss.length + " possibilities of compatible macro impl signatures for macro def: ")(ddef.name) - val results = reqparamsss map (checkCompatibility(_, actparamss, reqres, actres)) - if (macroDebugVerbose) (reqparamsss zip results) foreach { case (reqparamss, result) => - println("%s %s".format(if (result.isEmpty) "[ OK ]" else "[FAILED]", reqparamss)) - result foreach (errorMsg => println(" " + errorMsg)) - } - - if (results forall (!_.isEmpty)) { - var index = reqparamsss indexWhere (_.length == actparamss.length) - if (index == -1) index = 0 - val mostRelevantMessage = results(index).head - compatibilityError(mostRelevantMessage) - } else { - assert((results filter (_.isEmpty)).length == 1, results) - if (macroDebugVerbose) (reqparamsss zip results) filter (_._2.isEmpty) foreach { case (reqparamss, result) => - println("typechecked macro impl as: " + reqparamss) - } - } + val errors = checkCompatibility(reqparamss, actparamss, reqres, actres) + if (errors.nonEmpty) compatibilityError(errors mkString "\n") } } diff --git a/test/files/neg/macro-invalidsig-params-namemismatch.check b/test/files/neg/macro-invalidsig-params-namemismatch.check index 00d781a2ac..f2639d9350 100644 --- a/test/files/neg/macro-invalidsig-params-namemismatch.check +++ b/test/files/neg/macro-invalidsig-params-namemismatch.check @@ -2,6 +2,7 @@ Impls_Macros_1.scala:8: error: macro implementation has wrong shape: required: (c: scala.reflect.macros.Context)(x: c.Expr[Int], y: c.Expr[Int]): c.Expr[Any] found : (c: scala.reflect.macros.Context)(y: c.Expr[Int], x: c.Expr[Int]): Nothing parameter names differ: x != y +parameter names differ: y != x def foo(x: Int, y: Int) = macro Impls.foo ^ one error found -- cgit v1.2.3 From 72518506a353fecd4a4927dfff18630329b1c4aa Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Wed, 15 Aug 2012 16:36:50 +0200 Subject: further cleanup of transformTypeTagEvidenceParams --- .../scala/tools/nsc/typechecker/Macros.scala | 37 ++++++++++++++-------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index ab2221a6c4..f5ab9c6dd5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -299,22 +299,31 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { macroTraceVerbose("macroImplSig is: ")(paramss, implRetTpe) } + /** Transforms parameters lists of a macro impl. + * The `transform` function is invoked only for AbsTypeTag evidence parameters. + * + * The transformer takes two arguments: a value parameter from the parameter list + * and a type parameter that is witnesses by the value parameter. + * + * If the transformer returns a NoSymbol, the value parameter is not included from the result. + * If the transformer returns something else, this something else is included in the result instead of the value parameter. + * + * Despite of being highly esoteric, this function significantly simplifies signature analysis. + * For example, it can be used to strip macroImpl.paramss from the evidences (necessary when checking def <-> impl correspondence) + * or to streamline creation of the list of macro arguments. + */ private def transformTypeTagEvidenceParams(paramss: List[List[Symbol]], transform: (Symbol, Symbol) => Symbol): List[List[Symbol]] = { - import definitions.{ AbsTypeTagClass, MacroContextClass } - if (paramss.isEmpty || paramss.last.isEmpty) - return paramss - - val ContextParam = paramss.head match { - case p :: Nil => p filter (_.tpe <:< definitions.MacroContextClass.tpe) - case _ => NoSymbol - } - def isTag(sym: Symbol): Boolean = (sym == AbsTypeTagClass) || (sym.isAliasType && isTag(sym.info.typeSymbol)) - def transformTag(param: Symbol): Symbol = param.tpe match { - case TypeRef(SingleType(NoPrefix, ContextParam), sym, tp :: Nil) if isTag(sym) => transform(param, tp.typeSymbol) - case _ => param + if (paramss.isEmpty || paramss.last.isEmpty) return paramss // no implicit parameters in the signature => nothing to do + if (paramss.head.isEmpty || !(paramss.head.head.tpe <:< MacroContextClass.tpe)) return paramss // no context parameter in the signature => nothing to do + def transformTag(param: Symbol): Symbol = param.tpe.dealias match { + case TypeRef(SingleType(SingleType(NoPrefix, c), universe), typetag, targ :: Nil) + if c == paramss.head.head && universe == MacroContextUniverse && typetag == AbsTypeTagClass => + transform(param, targ.typeSymbol) + case _ => + param } - val last = paramss.last map transformTag filterNot (_ eq NoSymbol) - if (last.isEmpty) paramss.init else paramss.init :+ last + val transformed = paramss.last map transformTag filter (_ ne NoSymbol) + if (transformed.isEmpty) paramss.init else paramss.init :+ transformed } /** As specified above, body of a macro definition must reference its implementation. -- cgit v1.2.3 From 3c4ccbd6588caa88f3e7de6f687c885bd3ee6682 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Thu, 16 Aug 2012 01:39:37 +0200 Subject: more macro cleanup --- .../scala/tools/nsc/typechecker/Macros.scala | 50 +++++----------------- 1 file changed, 11 insertions(+), 39 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index f5ab9c6dd5..d87c864491 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -275,9 +275,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { val paramCache = collection.mutable.Map[Symbol, Symbol]() def param(tree: Tree): Symbol = paramCache.getOrElseUpdate(tree.symbol, { - // [Eugene] deskolemization became necessary once I implemented inference of macro def return type - // please, verify this solution, but for now I'll leave it here - cargo cult for the win - val sym = tree.symbol.deSkolemize + val sym = tree.symbol val sigParam = makeParam(sym.name, sym.pos, implType(sym.isType, sym.tpe)) if (sym.isSynthetic) sigParam.flags |= SYNTHETIC sigParam @@ -479,22 +477,14 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { macroTraceVerbose("body of a macro def failed to typecheck: ")(ddef) } else { if (!hasError) { - if (macroImpl == null) { - invalidBodyError() - } else { - if (!macroImpl.isMethod) - invalidBodyError() - if (!macroImpl.isPublic) - reportError(implpos, "macro implementation must be public") - if (macroImpl.isOverloaded) - reportError(implpos, "macro implementation cannot be overloaded") - if (!macroImpl.typeParams.isEmpty && (!rhs1.isInstanceOf[TypeApply])) - reportError(implpos, "macro implementation reference needs type arguments") - if (!hasError) - validatePostTyper(rhs1) + if (macroImpl == null) invalidBodyError() + else { + if (!macroImpl.isMethod) invalidBodyError() + if (!macroImpl.isPublic) reportError(implpos, "macro implementation must be public") + if (macroImpl.isOverloaded) reportError(implpos, "macro implementation cannot be overloaded") + if (!macroImpl.typeParams.isEmpty && !rhs1.isInstanceOf[TypeApply]) reportError(implpos, "macro implementation reference needs type arguments") + if (!hasError) validatePostTyper(rhs1) } - if (hasError) - macroTraceVerbose("macro def failed to satisfy trivial preconditions: ")(macroDef) } if (!hasError) { bindMacroImpl(macroDef, rhs1) // we must bind right over here, because return type inference needs this info @@ -631,29 +621,11 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { } def computeMacroDefTypeFromMacroImpl(macroDdef: DefDef, macroDef: Symbol, macroImpl: Symbol): Type = { - // get return type from method type - def unwrapRet(tpe: Type): Type = { - def loop(tpe: Type) = tpe match { - case NullaryMethodType(ret) => ret - case mtpe @ MethodType(_, ret) => unwrapRet(ret) - case _ => tpe - } - - tpe match { - case PolyType(_, tpe) => loop(tpe) - case _ => loop(tpe) - } - } - var metaType = unwrapRet(macroImpl.tpe) - // downgrade from metalevel-0 to metalevel-1 - def inferRuntimeType(metaType: Type): Type = metaType match { - case TypeRef(pre, sym, args) if sym.name == tpnme.Expr && args.length == 1 => - args.head - case _ => - AnyClass.tpe + var runtimeType = macroImpl.tpe.finalResultType.dealias match { + case TypeRef(pre, sym, runtimeType :: Nil) if sym == ExprClass => runtimeType + case _ => AnyTpe } - var runtimeType = inferRuntimeType(metaType) // transform type parameters of a macro implementation into type parameters of a macro definition runtimeType = runtimeType map { -- cgit v1.2.3 From 4667c6ec8e719cef8386a37335f27ba822772a6d Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Thu, 16 Aug 2012 07:41:44 +0200 Subject: pull request feedback --- src/compiler/scala/tools/nsc/typechecker/Macros.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index d87c864491..4765bbabc9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -623,7 +623,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { def computeMacroDefTypeFromMacroImpl(macroDdef: DefDef, macroDef: Symbol, macroImpl: Symbol): Type = { // downgrade from metalevel-0 to metalevel-1 var runtimeType = macroImpl.tpe.finalResultType.dealias match { - case TypeRef(pre, sym, runtimeType :: Nil) if sym == ExprClass => runtimeType + case TypeRef(_, ExprClass, runtimeType :: Nil) => runtimeType case _ => AnyTpe } -- cgit v1.2.3